3

我想将一个函数应用于匹配两个不同子字符串的选定列。我发现这篇文章与我的问题有关,但我无法从那里得到答案。

这是我失败的尝试的可重现示例。为了这个例子,我想做一个逐行操作,对所有以 string 开头的列的值求和,v并从所有以f.

更新:建议的解决方案必须(a)使用:=运算符来充分利用data.table快速性能,以及(2)对其他操作灵活,而不是meanand sum,我在这里使用它只是为了简单起见

library(data.table)

# generate data
  dt <- data.table(id= letters[1:5],
                   v1= 1:5, 
                   v2= 1:5,
                   f1= 11:15,
                   f2= 11:15)

dt
#>    id v1 v2 f1 f2
#> 1:  a  1  1 11 11
#> 2:  b  2  2 12 12
#> 3:  c  3  3 13 13
#> 4:  d  4  4 14 14
#> 5:  e  5  5 15 15

# what I've tried
  dt[, Y := sum( .SDcols=names(dt) %like% "v" ) - mean( .SDcols=names(dt) %like% "f" ) by = id]
4

2 回答 2

2

我们melt将数据集转换为'long'格式,通过使用参数,得到'v'和'f'measure之间的差异,按'id'分组,将'id'列与原始数据集连接并分配() 'V1' 作为 'Y' 变量summeanon:=

dt[melt(dt, measure = patterns("^v", "^f"), value.name = c("v", "f"))[
         , sum(v) - mean(f), id], Y :=V1,  on = .(id)]

dt
#   id v1 v2 f1 f2  Y
#1:  a  1  1 11 11 -9
#2:  b  2  2 12 12 -8
#3:  c  3  3 13 13 -7
#4:  d  4  4 14 14 -6
#5:  e  5  5 15 15 -5

或者另一种选择是Reduce在创建索引或“v”和“f”列之后

nmv <- which(startsWith(names(dt), "v"))
nmf <- which(startsWith(names(dt), "f"))
l1 <- length(nmv)
dt[, Y := Reduce(`+`, .SD[, nmv, with = FALSE])- (Reduce(`+`, .SD[, nmf, with  = FALSE])/l1)]
于 2017-06-15T15:02:11.993 回答
0

rowSumsrowMeans结合grep可以做到这一点。

dt$Y <- rowMeans(dt[,grep("f", names(dt)),with=FALSE]) - rowSums(dt[,grep("v", names(dt)),with=FALSE])
于 2017-06-15T14:41:57.517 回答