【问题标题】:Spread multiple coordinated columns分布多个协调列
【发布时间】:2015-10-19 15:37:06
【问题描述】:

我有相对整齐的数据,样本、基因、等位基因和频率分别位于不同的列中。对于每个基因和每个样本,我需要将等位基因及其相应的频率分成单独的列。这就是我拥有的和需要的。

尝试使用 dplyr/tidyr 执行此操作,但我会采取任何我能得到的解决方案。

我有什么:

data.frame(sample=rep("sample1", 10), 
           gene=rep(paste0("gene", 1:5), each=2), 
           allele=c("A", "G", "A", "C", "A", "T", "C", "G", "G", "T"), 
           freq=c(.9, .1, .8, .2, .7, .3, .6, .4, .5, .5))

#     sample  gene allele freq
# 1  sample1 gene1      A  0.9
# 2  sample1 gene1      G  0.1
# 3  sample1 gene2      A  0.8
# 4  sample1 gene2      C  0.2
# 5  sample1 gene3      A  0.7
# 6  sample1 gene3      T  0.3
# 7  sample1 gene4      C  0.6
# 8  sample1 gene4      G  0.4
# 9  sample1 gene5      G  0.5
# 10 sample1 gene5      T  0.5

我想要什么:

data.frame(sample=rep("sample1", 5), 
           gene=paste0("gene", 1:5), 
           allele1=c("A", "A", "A", "C", "G"), 
           allele2=c("G", "C", "T", "G", "T"), 
           freq1=c(.9, .8, .7, .6, .5), 
           freq2=c(.1, .2, .3, .4, .5))

#    sample  gene allele1 allele2 freq1 freq2
# 1 sample1 gene1       A       G   0.9   0.1
# 2 sample1 gene2       A       C   0.8   0.2
# 3 sample1 gene3       A       T   0.7   0.3
# 4 sample1 gene4       C       G   0.6   0.4
# 5 sample1 gene5       G       T   0.5   0.5

【问题讨论】:

  • 请不要在行首包含“>”和“+”;它们使复制粘贴代码变得更加困难。

标签: r


【解决方案1】:

您可以使用data.tableie 的开发版本中的dcast。 1.9.5+ 可以采用多个 value.var 列。我们创建一个按“sample”和“gene”分组的序列列(“indx”)。然后dcast 从长格式到宽格式提到value.var 列。

 library(data.table)#v1.9.5+ 
 setDT(df)[, indx:=1:.N,.(sample, gene)]
 dcast(df, sample+gene~indx, value.var=c('allele', 'freq'), sep= '')
 #    sample  gene   allele1 allele2  freq1 freq2
 #1: sample1 gene1        A        G    0.9    0.1
 #2: sample1 gene2        A        C    0.8    0.2
 #3: sample1 gene3        A        T    0.7    0.3
 #4: sample1 gene4        C        G    0.6    0.4
 #5: sample1 gene5        G        T    0.5    0.5

注意:安装devel版本的说明是here

sep='' 参数对于将列名称创建为“allele1”、“allele2”等很有用。默认值为“allele_1”、“allele_2”等(来自@Arun 的 cmets)

【讨论】:

    【解决方案2】:

    这使用汇总而不是真正的重塑,但可能符合要求。

    library(dplyr)
    foo <- data.frame(sample=rep("sample1", 10), 
                      gene=rep(paste0("gene", 1:5), each=2), 
                      allele=c("A", "G", "A", "C", "A", "T", "C", "G", "G", "T"), 
                      freq=c(.9, .1, .8, .2, .7, .3, .6, .4, .5, .5))
    
    foo %>%
      group_by(sample, gene) %>% 
      summarise(allele1 = first(allele), allele2 = last(allele),
                freq1 = first(freq), freq2 = last(freq))
    
    ## Source: local data frame [5 x 6]
    ## Groups: sample
    ## 
    ##    sample  gene allele1 allele2 freq1 freq2
    ## 1 sample1 gene1       A       G   0.9   0.1
    ## 2 sample1 gene2       A       C   0.8   0.2
    ## 3 sample1 gene3       A       T   0.7   0.3
    ## 4 sample1 gene4       C       G   0.6   0.4
    ## 5 sample1 gene5       G       T   0.5   0.5
    

    【讨论】:

      【解决方案3】:

      您可以自行加入表格,然后选择适当的行。

      library(dplyr)
      
      table <- data.frame(sample=rep("sample1", 10), 
                    gene=rep(paste0("gene", 1:5), each=2), 
                    allele=c("A", "G", "A", "C", "A", "T", "C", "G", "G", "T"), 
                    freq=c(.9, .1, .8, .2, .7, .3, .6, .4, .5, .5))
      
      inner_join(table, table, by=c("sample","gene")) %>%
      filter(allele.x != allele.y,
            (freq.x > freq.y | (freq.x == freq.y & as.numeric(allele.x) < as.numeric(allele.y))))
      

      【讨论】:

      • 这只有在我们知道等位基因不可能相同的情况下才有效,对吧?
      【解决方案4】:

      如果数据按样本和基因列排序,并且每个基因有 2 行,那么我们可以尝试如下:

      cbind( df[ seq(1,nrow(df),2), ],
             df[ seq(2,nrow(df),2), -c(1,2) ] ) 
      
      #output
      #    sample  gene allele freq allele freq
      # 1 sample1 gene1      A  0.9      G  0.1
      # 3 sample1 gene2      A  0.8      C  0.2
      # 5 sample1 gene3      A  0.7      T  0.3
      # 7 sample1 gene4      C  0.6      G  0.4
      # 9 sample1 gene5      G  0.5      T  0.5
      

      【讨论】:

        【解决方案5】:

        我自己也在纠结这个问题。经典的重塑可以说是这里最清晰的?

        df <- data.frame(sample=rep("sample1", 10), 
                   gene=rep(paste0("gene", 1:5), each=2), 
                   allele=c("A", "G", "A", "C", "A", "T", "C", "G", "G", "T"), 
                   freq=c(.9, .1, .8, .2, .7, .3, .6, .4, .5, .5))
        
        # make a time index
        df$time = as.numeric( duplicated( df$gene ) ) # rep( c(1,2), nrow(df)/2 )
        # reshape
        reshape( df, idvar="gene", v.names=c("allele", "freq"), timevar="time", direction="wide")
        

        但我真的很想从 tidyverse 得到一个干净的答案!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-29
          • 1970-01-01
          • 2012-01-08
          • 2013-10-05
          • 1970-01-01
          相关资源
          最近更新 更多