【问题标题】:R Merging data frames sequentially summing elemets - tricky.R合并数据帧顺序求和元素 - 棘手。
【发布时间】:2018-01-07 07:20:11
【问题描述】:

我有一系列要合并的数据框,按顺序对特定元素求和。作为背景,这些是基因组序列数据的单独分区文件,它们沿着比对引用基因区域(将其视为字符串的部分)。我已将序列比对合并在一起,因此需要将分区文件合并在一起,同时保留分区的相对位置。最好让它尽可能通用以适应任何数量和长度的单个分区文件。

合并和求和需要像这样工作:

  1. 第二列元素是前一行的第三列元素加一。
  2. 对于第一个数据帧,第三列:第一个元素等于 n,第二个元素等于 2n,第三个元素是 3n,依此类推。
  3. 在新合并的数据帧中,第三列的第一个元素将变为其值 (x) 加上前一个数据帧中第三列的最后一个元素 (x + ?n)。然后将 x 添加到每一行的 x + ?n 中,直到数据框结束或合并新的数据框。

一个简单的例子会更好地解释。

这是区域 1 的数据框:

                  V1    V2    V3 
Region_1_Partition_1     1   500
Region_1_Partition_2   501  1000
Region_1_Partition_3  1001  1500

这里是区域 2:

                  V1    V2   V3 
Region_2_Partition_1     1  200
Region_2_Partition_2   201  400
Region_2_Partition_3   401  600

最终的分区文件需要是这样的:

                  V1    V2    V3 
Region_1_Partition_1     1   500
Region_1_Partition_2   501  1000
Region_1_Partition_3  1001  1500
Region_2_Partition_1  1501  1700
Region_2_Partition_2  1701  1900
Region_2_Partition_3  1901  2001

我想到目前为止我还没有找到许多巧妙的解决方案!

谢谢 C

【问题讨论】:

    标签: r matrix merge


    【解决方案1】:

    编辑:抱歉,我通常浏览 data.table() 特定问题,但没有注意到这个问题是关于数据框的!相应地改变了我的答案

    我会将“n”保留为一列,以便您可以在最后一帧中 cumsum() 它。我不会通过merge 而是通过rbind() 实现这一目标

    首先“重新创建”您的数据

    region1 <- data.frame(
      label=c('Region_1_Partition_1', 'Region_1_Partition_2', 
    'Region_1_Partition_3'),
      V4=500
    )
    
    region1$V3 <- cumsum(region1$V4)
    region1$V2 <- region1$V3 - region1$V4 + 1
    region1[, c('label', 'V2', 'V3')]
    

    最后一条命令返回

                      label   V2   V3
    1: Region_1_Partition_1    1  500
    2: Region_1_Partition_2  501 1000
    3: Region_1_Partition_3 1001 1500
    

    类似的代码,用V4=200可以给region2。

    现在执行你的组合,

    out <- rbind(region1[, c('label', 'V4')], region2[, c('label', 'V4')])
    
    out$V3 <- cumsum(out$V4)
    out$V2 <- out$V3 - out$V4 + 1
    out[, c('label', 'V2', 'V3')]
    
    
                      label   V2   V3
    1: Region_1_Partition_1    1  500
    2: Region_1_Partition_2  501 1000
    3: Region_1_Partition_3 1001 1500
    4: Region_2_Partition_1 1501 1700
    5: Region_2_Partition_2 1701 1900
    6: Region_2_Partition_3 1901 2100
    

    另一个编辑:如何将解决方案扩展到更多的分区。

    我可以在这里看到两个挑战,第一个是需要rbind() 所有的东西,第二个是需要确定在V4 列中使用什么。

    可能有一种更有效的 R 方式来执行此操作(例如将所有表存储在一个列表中,然后将它们展平为一个表)。我只会使用 for 循环。

    假设您将所有文件名放在一个名为 files 的向量中。

    out <- data.frame()
    for (file in files) {
    
      # read the file. prepend a path before this step if necessary
      data <- read.csv(file)
    
      # determine V4.  This assumes that V3 is guaranteed to have a constant difference in any given file 
      # and that the first row is that difference, as in your example data
      data$V4 <- data$V3[1]
    
      data <- data[, c('V1', 'V4')] #note that I switched my first colname to match yours
    
      out <- rbind(out, data)
    }
    
    # Recover V2 and V3
    out$V3 <- cumsum(out$V4)
    out$V2 <- out$V3 - out$V4 + 1
    out[, c('V1', 'V2', 'V3')]
    

    请注意,您的文件必须有序,否则cumsum() 将不正确。如果文件不按顺序排列,您可以在构建 te out 表之后和使用 cumsum() 之前重新排序它们

    【讨论】:

    • 刚试过这个,效果很好。您对扩大规模有什么建议吗?比如我在 .csv 中有 20 多个单独的分区文件?
    • 我已经编辑了答案以包括我解决这个问题的尝试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多