如果您想要一个元素明智的加法,那么只需 + 而不是 sum 将向量的所有元素加在一起。此外,由于+ 只接受两个参数,所以不能使用超过两列的do.call,而需要Reduce():
x[, A := Reduce("+", .SD), .SDcols = columnsSelected]
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species A
# 1: 5.1 3.5 1.4 0.2 setosa 8.6
# 2: 4.9 3.0 1.4 0.2 setosa 7.9
# 3: 4.7 3.2 1.3 0.2 setosa 7.9
# 4: 4.6 3.1 1.5 0.2 setosa 7.7
# 5: 5.0 3.6 1.4 0.2 setosa 8.6
# ---
# 146: 6.7 3.0 5.2 2.3 virginica 9.7
# 147: 6.3 2.5 5.0 1.9 virginica 8.8
# 148: 6.5 3.0 5.2 2.0 virginica 9.5
# 149: 6.2 3.4 5.4 2.3 virginica 9.6
# 150: 5.9 3.0 5.1 1.8 virginica 8.9
正如@42 所评论的,我们通过将columnsSelected 变量扩展到三列来了解do.call() 和Reduce() 如何使用+ 和paste() 等函数:
columnsSelected = c("Sepal.Width", "Sepal.Length", "Petal.Length")
do.call("+", ...) 给出了预期的错误,因为“+”是一个二元运算符并且不接受两个以上的参数,而do.call() 给它三个参数(columnsSelected 中的三列;@ 987654336@ 按预期工作,因为Reduce() 逐列添加,而不是像do.call 那样一次将所有列传递给函数。对于paste,do.call() 和Reduce() 都可以工作,因为paste() 可以接受两个或多个向量作为参数。在这种情况下,do.call() 在您有很多列时更有效,但如果您只传入两列或三列,则在这里应该无关紧要。
x[, A := do.call(paste, .SD), .SDcols = columnsSelected]
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species A
# 1: 5.1 3.5 1.4 0.2 setosa 3.5 5.1 1.4
# 2: 4.9 3.0 1.4 0.2 setosa 3 4.9 1.4
# 3: 4.7 3.2 1.3 0.2 setosa 3.2 4.7 1.3
# 4: 4.6 3.1 1.5 0.2 setosa 3.1 4.6 1.5
# 5: 5.0 3.6 1.4 0.2 setosa 3.6 5 1.4
# ---
# 146: 6.7 3.0 5.2 2.3 virginica 3 6.7 5.2
# 147: 6.3 2.5 5.0 1.9 virginica 2.5 6.3 5
# 148: 6.5 3.0 5.2 2.0 virginica 3 6.5 5.2
# 149: 6.2 3.4 5.4 2.3 virginica 3.4 6.2 5.4
# 150: 5.9 3.0 5.1 1.8 virginica 3 5.9 5.1
而x[, A := Reduce(paste, .SD), .SDcols = columnsSelected] 的结果与do.call() 相同。
更新:
要将参数传递给do.call() 和Reduce 中的函数,do.call() 将列表参数中的参数展平并将它们视为单独的,因此为了将参数传递给do.call() 中的函数,我们可以连接列表参数的命名参数,即:
x[, A := do.call(paste, c(sep = ",", .SD)), .SDcols = columnsSelected]
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species A
# 1: 5.1 3.5 1.4 0.2 setosa 3.5,5.1,1.4
# 2: 4.9 3.0 1.4 0.2 setosa 3,4.9,1.4
# 3: 4.7 3.2 1.3 0.2 setosa 3.2,4.7,1.3
# 4: 4.6 3.1 1.5 0.2 setosa 3.1,4.6,1.5
# 5: 5.0 3.6 1.4 0.2 setosa 3.6,5,1.4
# ---
# 146: 6.7 3.0 5.2 2.3 virginica 3,6.7,5.2
# 147: 6.3 2.5 5.0 1.9 virginica 2.5,6.3,5
# 148: 6.5 3.0 5.2 2.0 virginica 3,6.5,5.2
# 149: 6.2 3.4 5.4 2.3 virginica 3.4,6.2,5.4
# 150: 5.9 3.0 5.1 1.8 virginica 3,5.9,5.1
另一方面,对于Reduce(),它允许你重构一个匿名函数,你可以创建一个带有sep参数的自定义函数:
x[, A := Reduce(function(x,y) paste(x,y,sep=","), .SD), .SDcols = columnsSelected]
再次给出与do.call() 相同的结果。