如何组合具有相似值的行?

时间:2014-06-20 21:02:22

标签: r dataframe

我想将行组合在一起,并将它们的平均值用作新行。这很难解释,所以我试图展示一个例子:

  row  chr    pos methbulk htcmeth   dist
    1 chr1     10        0     100     NA
    2 chr1 100010      100       0 100000 #
    3 chr1 100020      100       0     10 # These 3 rows should be merged 
    4 chr1 100030      100       0     10 # because their "pos" is close
    5 chr1 250030      100       0 150000
    6 chr1 350030      100      23 100000
 ....
   51 chr2 200000        0     100     NA # the methbulk and htcmeth rows should be 
   52 chr2 200010      100       0     10 # averaged when these two rows are merged
   53 chr2 300020      100       0 100010 
   54 chr2 300030      100       0     10
   55 chr2 300040      100       0     10
   56 chr2 300050      100       0     10

这里,pos是"位置"一条线位于,而dist是距离"从上一行减去的当前行的pos,由ddply(data, .(chr), transform, dist=c(NA,diff(pos)))

计算

理想情况下,每2行或更多行(距离(dist)彼此接近(例如1000)应折叠成一行,并采集和报告甲基和平均值。完成此操作后,不再需要dist列。相反,一个新列,"结束"应指定最高的" pos"所有合并行的值。

因此,上述数据应该是这样的:

  row  chr    pos methbulk htcmeth   end
    1 chr1     10        0     100     10
    2 chr1 100010      100       0 100030
    5 chr1 250000      100       0 250000 #the merged rows
    6 chr1 350000      100      23 350000
 ....
   51 chr2 200000       50      50 200010 #the average values have been taken here
   53 chr2 300020      100       0 300050

有什么想法吗?是否有必要使用距离测量?我正在考虑使用基于距离测量的逻辑矢量(即,如果距离<1000,则行直到距离> 1000)

编辑:4行或更多行怎么样?答案会有显着变化吗?

2 个答案:

答案 0 :(得分:2)

创建一个新列,用于确定将数据放入哪个“bin”。

首先,将NA中的dist值替换为大于容差的值,然后使用逻辑向量上的cumsum作为二进制数:

tol = 1000
x$dist[is.na(x$dist)] <- tol + 1
x$bin <- cumsum(x$dist > tol)
aggregate(. ~ bin, data=x, FUN=mean)
##   bin  row chr    pos methbulk htcmeth     dist
## 1   1  1.0   1     10        0     100   1001.0
## 2   2  3.0   1 100020      100       0  33340.0
## 3   3  5.0   1 250030      100       0 150000.0
## 4   4  6.0   1 350030      100      23 100000.0
## 5   5 51.5   2 200005       50      50    505.5
## 6   6 54.5   2 300035      100       0  25010.0

然后删除不需要的列。

请注意,这也会返回pos列的平均值。

答案 1 :(得分:0)

也许定义一个聚合向量:

dat$farcat <-  ave( dat$pos, dat$chr, FUN= function(x) cumsum(1, diff(x)>1000) )

然后聚合'farcat'值,这些值现在为每条染色体单独处理:

 aggregate( pos+methbulk ~ chr+closecat, data=dat)    # default fun is mean

如果您还想要聚合组的启动和停止,那么使用聚合也很容易。可以是cbind() - 编写前面的答案

aggregate(pos ~ chr + farcat, data=dat, FUN=function(x) { c(min=min(x), max=max(x))} )