按组添加总计数据列,空行为R

时间:2017-06-13 14:47:25

标签: r

我正在尝试向数据集添加一列,该数据集显示另一列中每个组ID的一列中的数据总和。总和或总列将具有空行,每组一个总和。

aggregate(Diff ~ Group, data.set, sum)给了我正确的总和,但是除去了所有其他行。虽然像: data.set$Total <- ave(data.set$Diff, factor(data.set$Group), FUN=sum);给了我新的列Total但没有值。例如,输入数据集如下所示:

Group  Diff
1 
1     -16055
1     -1313
1      45707
1      6569
2 
2     -7249
2      2
3 
3     -384724

我希望输出看起来像这样:

Group   Diff  Total
1 
1     -16055
1     -1313
1      45707
1      6569     34908 
2 
2     -7249
2      2       -7247
3 
3     -384724  -384724

Diff列是先前计算的结果,它找到另一列中值的差异,因此每个组的第一行为空。类似的例子显示了获取一列中的值和一些按组显示的值,但似乎没有一个显示如何实现与我需要的输出一致的结果。谢谢你的帮助

4 个答案:

答案 0 :(得分:1)

假设您的LinkPager列是数字且空白真的是Diff,您可以这样做:

NA

或者你可以根据弗兰克在评论中的建议进行合并:

library(data.table)
dt <- data.table(Group = c(1,1,1,1,1,2,2,2,3,3), Diff = c(NA,-16055,-1313, 45707,6569,NA,-7249,2,NA,-384724))

dt[,total := ifelse(seq_len(.N) == .N, sum(Diff, na.rm = T), NA), by = Group]

 #   Group    Diff   total
 #1:     1      NA      NA
 #2:     1  -16055      NA
 #3:     1   -1313      NA
 #4:     1   45707      NA
 #5:     1    6569   34908
 #6:     2      NA      NA
 #7:     2   -7249      NA
 #8:     2       2   -7247
 #9:     3      NA      NA
#10:     3 -384724 -384724

时间比较:

要了解@ Frank的合并选项和我原来的解决方案之间的时序比较,我改变了#组和#观察(两者的高和低选项)并在4个单独的上运行了微基准测试数据集。结果如下,看起来无论如何其他Frank的合并选项是最快的。我认为我的解决方案中的瓶颈是dt[dt[, sum(Diff, na.rm=TRUE), by=Group], on=.(Group), mult="last", total := i.V1 ] ,如果你可以删除它,它可能会更快,尽管有多少是不确定的。

ifelse

答案 1 :(得分:0)

试试这个。我们首先聚合,然后合并到您现有的数据集

result <- merge(data.set,setNames(aggregate(Diff ~ Group, data.set, sum),c("Group","Total")),all.x=TRUE)

如果您不想重复总计,请添加result$Total[-cumsum(table(data.set$Group))] <- ""result$Total[-cumsum(table(data.set$Group))] <- NA

答案 2 :(得分:0)

如果34908出现在每个“1”前面,不仅仅是在最后一个前面吗?

如果不是,您可以在库“sqldf”中使用它:

library(sqldf)

data_count = sqldf('select groupe, sum(diff) as Total from data group by groupe')
new_data = sqldf('select * from data as a inner join data_count as b on a.groupe = b.groupe')

另外,如果您真的想要NA,请添加以下内容:

 for (i in 1:(dim(new_data)[1]-1)){
  if (new_data[i,"groupe"] == new_data[i+1,"groupe"]){
    new_data[i,'Total'] = NA
  }
}

答案 3 :(得分:0)

使用split/unsplit的另一种可行方法:

DF <- data.frame(Group=c(1,1,1,1,1,2,2,2,3,3), 
                 Diff=c(NA,-16055,-1313,45707,6569,NA,-7249,2,NA,-384724))

customSum <- function(x){ 
  v <- x
  v[] <- NA
  v[length(v)] <- sum(x,na.rm = T)
  return(v)
}
DF$Total <- unsplit(lapply(split(DF$Diff,DF$Group),customSum),DF$Group)

> DF
   Group    Diff   Total
1      1      NA      NA
2      1  -16055      NA
3      1   -1313      NA
4      1   45707      NA
5      1    6569   34908
6      2      NA      NA
7      2   -7249      NA
8      2       2   -7247
9      3      NA      NA
10     3 -384724 -384724