我希望按组对每列进行求和。在下面的示例中,我希望对(v1
和v2
),(v3
和v4
)和(v5
和v6
进行求和。 ),每个r1
,r2
和r3
。
我可以使用下面的sapply
语句执行此操作,我得到了正确的答案。但是,所需的代码很复杂。有人可以告诉我如何在包data.table
或rollapply
和/或其他选项中执行相同的操作吗?我还没有探讨过这些选择。
很抱歉,如果这是重复的话。
my.data <- read.table(text= "
r1 r2 r3 t1 t2 t3 v1 v2 v3 v4 v5 v6
1 0 0 10 20 30 1 0 0 0 0 0
1 0 0 10 20 30 1 1 0 0 0 0
1 0 0 10 20 30 1 0 1 0 0 0
1 0 0 10 20 30 1 0 1 1 0 0
1 0 0 10 20 30 0 0 0 0 0 0
0 1 0 10 20 30 0 1 1 1 1 1
0 1 0 10 20 30 0 0 1 1 1 1
0 1 0 10 20 30 0 0 0 1 1 1
0 1 0 10 20 30 0 0 0 0 1 1
0 1 0 10 20 30 0 0 0 0 0 1
0 0 1 10 20 30 1 1 1 1 1 1
0 0 1 10 20 30 1 0 1 1 1 1
0 0 1 10 20 30 1 0 0 1 1 1
0 0 1 10 20 30 1 0 0 0 1 1
0 0 1 10 20 30 1 0 0 0 0 1
", header=TRUE, na.strings=NA)
my.data$my.group <- which(my.data[,1:3]==1, arr.ind=TRUE)[,2]
my.data
my.sums <- t(sapply(split(my.data[,7:(ncol(my.data)-1)], my.data$my.group), function(i) sapply(seq(2, ncol(i), 2), function(j) sum(i[,c((j-1),j)], na.rm=TRUE))))
my.sums
# [,1] [,2] [,3]
# 1 5 3 0
# 2 1 5 9
# 3 6 5 9
答案 0 :(得分:4)
这是一个非常通用的表达式,如果您希望它与您的特定数据维度/列名称等匹配,您可以简化它们:
library(data.table)
dt = data.table(my.data)
dt[, lapply(1:(ncol(.SD)/2), function(x) sum(.SD[[2*x-1]], .SD[[2*x]])),
by = eval(grep('^r', names(dt), value = TRUE)),
.SDcols = grep('^v', names(dt), value = TRUE)]
# r1 r2 r3 V1 V2 V3
#1: 1 0 0 5 3 0
#2: 0 1 0 1 5 9
#3: 0 0 1 6 5 9
答案 1 :(得分:1)
另外,使用aggregate
和mapply
:
DF <- my.data
#function to sum 2 columns
fun <- function(col1, col2)
{
rowSums(aggregate(DF[c(col1, col2)], by = list(DF$r1, DF$r2, DF$r3), sum)[c(4, 5)])
}
#all pairs of columns, to be summed, in a matrix
#(7 is the column of v1)
args_mat <- matrix(7:ncol(DF), ncol = 2, byrow = T)
#apply `fun` to all pairs
mapply(fun, args_mat[,1], args_mat[,2])
# [,1] [,2] [,3]
#[1,] 5 3 0
#[2,] 1 5 9
#[3,] 6 5 9