2013-06-12 73 views
4

我有一个行数非常大且只有两个配对列的矩阵。我想计算第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) 

和结果矩阵是

A  B 
185.0765 10 
185.3171 20 
186.0779 35 
188.0078 50 

我会感激,如果有人能请咨询我如何为大量的行做到这一点。我认为使用for循环不会很有效。

+0

+1用于输入数据和期望的输出以及有趣的问题。 –

回答

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 

的想法是,我们使用的累加值发现有< 0.001的差异A组。如果差异低于此阈值,我们会在我们的Group列中放入0,因此在累计总和中它将成为同一组的一部分。

至于建议的@eddi这样做是做分组和计算都在同一时间,在一个呼叫的更简洁和有效的方式:

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

顺便说一句,拥有绝对数量的行总是有帮助的。 A 非常大的数字对不同的人和用例而言意味着不同的东西。我们正在说万元吗?亿万?

+2

+1这是'.SD'的理想用法,因为它使用'.SD'中的所有信息。使用'.SD'的主要低效率是如果从中取得一部分行;例如,头(.SD,2)浪费地创建了所有的“.SD”,即使只需要前两行。但是通过'.SD'的'lapply'使用了所有的数据,而'.SD'就是这样,尤其是'.SDcols'。 –

+0

@MatthewDowle啊好吧,我想我正在慢慢开始理解'.SD'和美妙的'data.table'软件包! (感谢和一个帽子!) –

+0

@ SimonO101这样做的技巧。感谢您的帮助。:) – jsin