如何有效地将R中的两个数据帧合并为一个,重新计算每个新单元格的值(最好使用dplyr)

时间:2018-11-14 09:46:50

标签: r dataframe dplyr

我有一个MySQL表,其中包含有关我正在进行的某些分析的数据。看起来像这样:mySQL table

这也是与此表相对应的示例数据集:

species  chrom  pos   strand  ratio   coverage  context  

X        Y      64    +       0.25    12        TACGT  

X        Y      65    -       0.5     20        ACGTT

X        Y      107   +       0.8     10        CCCGT  

X        Y      108   -       0.4     30        CCGTG

如您所见,我目前有一个包含7个字段的表格。我想做的是将“ plus”链的所有单元格与下一个“-”链的单元格合并。然后,我将得到一个新表,该表包含6个字段(除strand字段以外的所有字段)和旧表的一半行。但是,我需要根据包含链信息的旧表的信息重新计算新表中每个单元格的内容。

因此,字段“ species”和“ chrom”包含要合并的每个单元格的相同信息。我只需要保留两者之一即可。对于字段pos,我只能保留“ +”链中的信息。与“上下文”字段相同。但是对于字段“ coverage”和“ ratio”,我需要执行计算。 “ coverage”字段将包含单元格,这些单元格将是“ +”和“-” coverage单元格的总和。 “比率”字段将使用以下函数进行计算:

new_ratio =(“ ratio +” *“ coverage +” +“ ratio-” *“ coverage-”)/“ coverage +” +“ coverage-”

所以这将是旧比率和覆盖率的函数。

新表应如下所示:

species  chrom  pos  ratio       coverage  context  

X        Y      64   0.40625     32        TACGT  

X        Y      107  0.5         40        CCCGT

我已经成功编写了一个脚本,该脚本可以完全按照我想要的方式创建一个新表,但是它要花很多时间(我在R中这样做)!

我正在做的是将表分为两个数据框,即“正”数据框和“负”数据框。然后,通过执行上述计算,逐行重新创建新表。

此代码效率很低,因为重新创建新表花费的时间太长。我的原始表格中有几千万个条目(:

是否有一种方法可以更有效地做到这一点,也许是通过立即组合我创建的“正”和“负”数据帧而不必逐行执行呢?

在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

# read in data
dat <- structure(list(species = c("X", "X", "X", "X"), chrom = c("Y", 
"Y", "Y", "Y"), pos = c(64L, 65L, 107L, 108L), strand = c("+", 
"-", "+", "-"), ratio = c(0.25, 0.5, 0.8, 0.4), coverage = c(12L, 
20L, 10L, 30L), context = c("TACGT", "ACGTT", "CCCGT", "CCGTG"
)), class = "data.frame", row.names = c(NA, -4L))

您可以根据链条条件将数据分为两部分,然后按种类和色度将两个数据帧合并在一起

dat[dat$strand == '+',] -> plus_strand
dat[dat$strand == '-',] -> minus_strand
merge(plus_strand, minus_strand, by=c('species','chrom')) -> newdat
# filter out lines where the difference between pos = 1    
newdat[newdat$pos.x - newdat$pos.y == -1,] -> newdat

合并后的数据如下:

> newdat
  species chrom pos.x strand.x ratio.x coverage.x context.x pos.y strand.y ratio.y coverage.y context.y
1       X     Y    64        +    0.25         12     TACGT    65        -     0.5         20     ACGTT
4       X     Y   107        +    0.80         10     CCCGT   108        -     0.4         30     CCGTG

我不知道如何退回上面列出的数字,但这似乎可以返回正确的行数。