2016-03-08 53 views
2

我想通过块来概括数字:总结号码由R中块

下面是一个示例数据

data=matrix(c(0,0,0,1,1,0,1,1,1,1,1,0,0,1,0,0,1.2,2.3,1.3,1.5,2.5,2.1,2.3,1.2), 
      ncol=3,dimnames=list(c(),c("low","high","time"))) 

    low high time 
[1,] 0 1 1.2 
[2,] 0 1 2.3 
[3,] 0 1 1.3 
[4,] 1 0 1.5 
[5,] 1 0 2.5 
[6,] 0 1 2.1 
[7,] 1 0 2.3 
[8,] 1 0 1.2 

我想获得

 n sum 
[1,] 3 4.8 
[2,] 2 4 
[3,] 1 2.1 
[4,] 2 3.5 

,而无需使用任何包。如何与R做到这一点?

或者,如果我能得到

 n/low n/high sum 
[1,] 0  3 4.8 
[2,] 2  0 4 
[3,] 0  1 2.1 
[4,] 2  0 3.5 
+2

请说明你到目前为止尝试过的。 – Andru

+0

我试过了(),aggregate()等。但我没有找到一个好的方法来应用这个问题的这些功能。所以基本上我完全不知道 – Yukun

+0

你现在有一个矩阵,如在例子或数据框?他们看起来相似,但是有差别 –

回答

9

不知道为什么在包装上的约束。他们可以使这更容易。我们可以使用前两列的唯一组合创建索引。然后与索引进行汇总以进行分组。添加一行最多设置名称和数据帧结构:

ind <- with(rle(do.call(paste, df1[1:2])), rep(1:length(values), lengths)) 
a <- aggregate(df1$time, list(ind), function(x) c(length(x), sum(x)))[-1] 
setNames(do.call(data.frame, a), c("n", "sum")) 

    n sum 
1 3 4.8 
2 2 4.0 
3 1 2.1 
4 2 3.5 

为了说明从data.table是多么简单的帮助:

library(data.table) 
setDT(df1)[, .(.N, sum(time)), by=rleid(low, high)] 

更新

对于后续问题,请参阅评论中的@bgoldst回答。

+0

你可以使用'base R'或'data.table'。有了'dplyr',你既可以与data.table结合使用,也可以使用索引方法http://stackoverflow.com/questions/33507868/is-there-a-dplyr-equivalent-to-data-tablerleid –

+0

什么是df1在这里? – Yukun

+0

这就是你输入数据帧名称的地方 –

3

一个类似的选项,也使用聚合;

aggregate(cbind(n=1,sum=df$time), 
      by=list(c(0, cumsum(abs(diff(df$low))))), 
      FUN=sum)[-1] 
+1

好的解决方案。也可以使用公式法:'aggregate(.g,cbind(df,g = c(0,cumsum(abs(diff(df $ low))))​​),sum)[ - 1]'。 – bgoldst

+0

非常感谢!这些解决方案打开了我的眼睛! – Yukun

0

我已经解决了这个问题,我认为这有点复杂,但它的工作原理。

那么,我已经使用循环生成每列。

1)我算

data<-data.frame(data) 
ind1<-vector(mode="numeric", length=0) 
ind1[1]<-1 
for(i in c(2:8)) 
    ind[i]<-ifelse(data[i,1:2]==data[i-1,1:2],ind1[i-1],ind1[i-1]+1) 

然后我就产生与循环也和每一个变化。

ind<-c(1.2,0,0,0) 
k<-1 

for(i in c(2:8)){ 
    if(data[i,1:2]==data[i-1,1:2]){ 
    ind2[k]<-ind2[k]+data[i,3] 
    }else{ 
     k<-k+1 
     ind2[k]<-ind2[k]+data[i,3] 
}} 


    result<-cbind(data.frame(table(ind1))$Freq,ind2) 

但是我收到了一些警告,但我认为这不是问题。

+0

只是一个建议,你的代码可以通过一些空间变得更易读。 – Gregor

+0

什么样的空间? – sanmath

+0

空格。 R的常用样式指南(例如[Google](https://google.github.io/styleguide/Rguide.xml)或[Hadley Wickham's](http://adv-r.had.co.nz/Style)。 )建议在每个逗号后面以及所有二元运算符(特别是赋值运算符“<-'”)之间使用空格。而不是'if(data [i,1:2] == data [i-1,1:2]){',你应该有'if(data [i,1:2] == data [i - 1 ,1:2]){'。它使读起来更容易,更快更好理解。 – Gregor

0

我也发现了类似的选择:

aggregate(df,list(c(0,cumsum(abs(diff(df$low))))),sum)[-1] 

对我来说是更直接的了解。