按组(在data.table中)对多个列进行加权

Peu*_*tch 6 r data.table

这个问题跟随另一个关于群体加权平均值的问题:我想用data.table.创建加权群内平均值.与初始问题的不同之处在于,要求平均的变量名称是在字符串向量中指定的.

数据:

df <- read.table(text= "
          region    state  county  weights y1980  y1990  y2000
             1        1       1       10     100    200     50
             1        1       2        5      50    100    200
             1        1       3      120    1000    500    250
             1        1       4        2      25    100    400
             1        1       4       15     125    150    200
             2        2       1        1      10     50    150
             2        2       2       10      10     10    200
             2        2       2       40      40    100     30
             2        2       3       20     100    100     10
", header=TRUE, na.strings=NA)
Run Code Online (Sandbox Code Playgroud)

使用Roland建议的答案来自上述问题:

library(data.table)
dt <- as.data.table(df)
dt2 <- dt[,lapply(.SD,weighted.mean,w=weights),by=list(region,state,county)]
Run Code Online (Sandbox Code Playgroud)

我有一个带字符串的向量来动态确定我想要组内加权平均值的列.

colsToKeep = c("y1980","y1990")
Run Code Online (Sandbox Code Playgroud)

但我不知道如何将它作为data.table魔法的参数传递.

我试过了

 dt[,lapply(
      as.list(colsToKeep),weighted.mean,w=weights),
      by=list(region,state,county)]` 
Run Code Online (Sandbox Code Playgroud)

但我得到:

Error in x * w : non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)

不知道如何实现我想要的.

奖金问题:我希望保留原始列名,而不是获得V1和V2.

NB我使用的是data.table包的1.9.3版本.

Aru*_*run 10

通常,您应该能够:

dt2 <- dt[,lapply(.SD,weighted.mean,w=weights), 
          by = list(region,state,county), .SDcols = colsToKeep]
Run Code Online (Sandbox Code Playgroud)

即,只提供那些列.SDcols.但目前,由于一个错误,这将不起作用,因为该weights列未指定,因此该列将不可用.SDcols.

在它修复之前,我们可以按如下方式完成:

dt2 <- dt[, lapply(mget(colsToKeep), weighted.mean, w = weights), 
            by = list(region, state, county)]
#    region state county     y1980    y1990
# 1:      1     1      1  100.0000 200.0000
# 2:      1     1      2   50.0000 100.0000
# 3:      1     1      3 1000.0000 500.0000
# 4:      1     1      4  113.2353 144.1176
# 5:      2     2      1   10.0000  50.0000
# 6:      2     2      2   34.0000  82.0000
# 7:      2     2      3  100.0000 100.0000
Run Code Online (Sandbox Code Playgroud)