大量行之间的差异

jsi*_*sin 4 r data.table

我有一个矩阵,有很多行,只有两个成对的列.我想计算第1列中每行之间的差异,如果差异小于预定义值(.001),则计算两列中这些行的平均值.例如,我有一个称为权重的矩阵,

  A      B
185.0765 10
185.3171 20
186.0777 30
186.0780 40
188.0078 50

weights<-as.data.table(weights)
bins<-weights[A %between% c(A[3],(A[3]+.001))]
meanA<-mean(bins$A)
meanB<-mean(bins$B)
Run Code Online (Sandbox Code Playgroud)

并且得到的矩阵将是,

  A      B
185.0765 10
185.3171 20
186.0779 35
188.0078 50
Run Code Online (Sandbox Code Playgroud)

如果有人可以建议我如何为大量行做这件事,我将感激不尽.我认为使用for循环不会非常有效.

Sim*_*lon 6

这应该达到你想要做的,使用data.table:

DT <- data.table( weights )
DT[ , Group :=( cumsum( c( 1 , ifelse( diff(weights$A) < 0.001 , 0 , 1 ) ) ) ) ]
DT[ , lapply(.SD, mean) , by=Group ,  .SDcols = c("A","B") ]
#   Group        A  B
#1:     1 185.0765 10
#2:     2 185.3171 20
#3:     3 186.0779 35
#4:     4 188.0078 50
Run Code Online (Sandbox Code Playgroud)

我们的想法是使用累积和来找到A差异<0.001的组.如果差异低于此阈值,我们0在我们的Group列中添加一个,因此在累积总和中它将成为同一组的一部分.

正如@eddi所建议的那样,更简洁有效的方法是在一次调用中同时进行分组和计算:

DT <- data.table( weights )
DT[ , lapply(.SD, mean) , by = list(Group = cumsum(c(1,diff(A)) >= 0.001)) ,  .SDcols = c("A","B") ]    
Run Code Online (Sandbox Code Playgroud)

另外,拥有绝对行数总是有帮助的.一个非常大的数字行意味着不同的事情不同的人,使用情况.我们在谈论百万吗?亿万?

  • 使用`by = list(Group = cumsum(c(1,diff(A))> = 0.001))`将在更少的行中实现完全相同的输出并且不使用`ifelse` (4认同)
  • +1这是`.SD`的理想用法,因为它使用`.SD`中的所有信息.使用`.SD`的主要低效率是从中获取行的子集; 例如,`head(.SD,2)`浪费地创建所有`.SD`,即使只需要前两行.但是``lapply`通过`.SD`使用所有的数据,并且``.SD`就在那里,特别是`.SDcols`. (3认同)
  • @eddi是的,这是有意的:`by`中使用的任何符号都被排除在`.SD`之外,因为大多数情况下都是需要的; 例如,`by = month(date)`.但如果需要,可以使用`.SDcols`强制它们进入`.SD`. (3认同)
  • @eddi,IIUC,我在data.table上也有[同样的问题](http://lists.r-forge.r-project.org/pipermail/datatable-help/2013-May/001760.html)邮件列表: (2认同)