这是数据:
data <-data.frame(
"start"= c("go",NA,NA,NA,"go",NA,"go"),
"number"= c(31,32,1,29,61,17,72),
"info"= c("c","k","s","u","b","i","n"))
start number info
1 go 31 c
2 <NA> 32 k
3 <NA> 1 s
4 <NA> 29 u
5 go 61 b
6 <NA> 17 i
7 go 72 n
我想制作一个汇总表,在开始 =“go”的每一行打印信息
但是,我希望数字列在“go”之后从所有单元格求和,直到下一个“go”,以便结果如下所示:
final <- data.frame(
"start"=c("go","go","go"),
"number"=c(93,78,72),
"info"=c("c","b","n"))
start number info
1 go 93 c
2 go 78 b
3 go 72 n
感谢您的帮助。
答案 0 :(得分:2)
基础R中的策略是执行子集化并在单独的操作中执行求和,然后将结果合并在一起。在这里,我们可以使用cbind
进行合并,因为这两个数据集的构造是为了排列。
cbind(data[!is.na(data$start), c(1, 3)],
sum=aggregate(number ~ cumsum(!is.na(start)), data=data, sum)[,2])
start info sum
1 go c 93
5 go b 78
7 go n 72
我使用!is.na
选择适当的行,这在本例中有效。如果您想要排除其他非NA值,则可以使用!is.na(data$start) & data$start == "go"
。 aggregate
用于执行求和,第二个参数中的分组使用相同的方法,但对结果执行累积求和。
答案 1 :(得分:1)
您可以使用dplyr:
data <-data.frame(
start= c("go",NA,NA,NA,"go",NA,"go"),
number= c(31,32,1,29,61,17,72),
info= c("c","k","s","u","b","i","n"),stringsAsFactors = F)
library(dplyr)
data$group = cumsum(!is.na(data$start))
data %>% group_by(group) %>% summarize(n=sum(number), info=info[1])
输出
group n info
1 1 93 c
2 2 78 b
3 3 72 n
您可以选择添加
%>% mutate(start="go") %>% select(-group)
获取您要求的输出,但我不确定这是否真的增加了价值。 希望这有帮助!
答案 2 :(得分:0)
以下是使用data.table
library(data.table)
setDT(data)[, .(start = start[!is.na(start)], n = sum(number),
info = info[1]), .(grp = cumsum(!is.na(start)))][, grp := NULL][]
# start n info
#1: go 93 c
#2: go 78 b
#3: go 72 n