时间:2016-08-30 13:34:43

标签: r data.table

如果我有以下数据表

m = matrix(1:12, ncol=4)
colnames(m) = c('A1','A2','B1','B2')
d = data.table(m)

是否可以对多组列执行函数?

例如,以下是A1,A2和B1,B2的总和。

   A  B
1: 5 17
2: 7 19
3: 9 21

该解决方案最好使用500k x 100矩阵

2 个答案:

答案 0 :(得分:1)

<强>解决方案

一个技巧是将split列分组。

然后你可以像Frank建议的那样使用rowSums(见问题评论):

# using your data example
m <- matrix(1:12, ncol = 4)
colnames(m) <- c('A1', 'A2', 'B1', 'B2')
d <- data.table(m)

# 1) group columns
groups <- split(colnames(d), substr(colnames(d), 1, 1))

# 2) group wise row sums
d[,lapply(groups, function(i) {rowSums(d[, i, with = FALSE])})]

<强>结果

这将返回data.table

   A  B
1: 5 17
2: 7 19
3: 9 21

<强>解释

  • split为每个组创建一个列名列表,由一个(强制为a)因子定义。
  • substr(colnames(m), 1, 1)将第一个字母作为组ID,使用不同的方法(例如sub("([A-Z]).*", "\\1", colnames(m))表示可变数量的字母)。
  • lapply通常用于在data.table中的多个列上应用函数。在这里,我们创建一个名为groups的列表输出,其中包含rowSums。使用with = FALSE的值从i获取相应列时,d非常重要。

答案 1 :(得分:0)

绝对可能 ...

d[, ":=" (A = A1 + A2, B = B1 + B2)]
d
   A1 A2 B1 B2 A  B
1:  1  4  7 10 5 17
2:  2  5  8 11 7 19
3:  3  6  9 12 9 21

# Want to drop the old columns?
set(d, j = which(names(d) %in% c("A1", "B1", "A2", "B2")), value = NULL)
d
   A  B
1: 5 17
2: 7 19
3: 9 21

是否可取,我不会说。可能更好地遵循弗兰克的建议(见评论)。