【问题标题】:Sum pairs of columns by group按组对列求和
【发布时间】:2013-10-28 19:59:10
【问题描述】:

我希望按组对列进行求和。在下面的示例中,我希望对 (v1v2)、(v3v4) 和 (v5v6) 求和,每个由 r1r2r3.

我可以使用下面的sapply 语句来做到这一点,我得到了正确的答案。但是,所需的代码很复杂。有人可以告诉我如何在包data.tablerollapply 和/或其他选项中执行相同的操作吗?我还没有探索过这些选项。

抱歉,如果这是重复的。

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

【问题讨论】:

  • 谢谢。我修好了它。我在发布前删除了一列,忘记修改分组代码。
  • 当你说“by r1, r2`, etc..”时分别是(相对于列对?)另外,是否有比本示例中更多的列,或者只是显示的那些在这里?
  • 真实数据集有 110 列或 55 对要求和,分组变量 r 从 1 到 5,而不是在本例中为 1 到 3。我不确定你的第一个问题是什么意思。

标签: r data.table sapply rollapply


【解决方案1】:

如果您希望它与您的特定数据维度/列名称/等匹配,您可以简化它:

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

【讨论】:

  • 不错!我期待看到一个 20 行的怪物答案。
【解决方案2】:

另外,使用aggregatemapply

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-23
    • 2019-02-17
    • 2021-02-28
    • 2019-03-06
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多