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

R 如何组合具有相似值的行?,r,dataframe,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

我希望将具有相近值的行组合起来,并将它们的平均值用作新行。这很难解释,因此我将尝试展示一个示例:

  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))

理想情况下,每两行或更多行之间的距离(dist)接近(如1000),应折叠成一行,并获取和报告methbulk和htcmeth的平均值。完成此操作后,不再需要dist列。相反,新列“end”应该指定所有合并行的最高“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行或更多行怎么样?答案是否有显著变化?

创建一个新列,确定将数据放入哪个“箱子”

首先,用大于公差的值替换
dist
中的
NA
值,然后使用逻辑向量上的
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
tol=1000

x$dist[is.na(x$dist)]可以定义一个聚合向量:

dat$farcat <-  ave( dat$pos, dat$chr, FUN= function(x) cumsum(1, diff(x)>1000) )
如果您还需要聚合组的开始和停止,那么使用聚合也很容易。可能是cbind()-ed到前面的答案

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

啊,这是一个有趣的方法。然后,我是否可以获得每个“箱子”位置的最小值和最大值,以获得起点和终点?
aggregate(pos ~ chr + farcat, data=dat, FUN=function(x) { c(min=min(x), max=max(x))} )