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

时间:2014-09-24 14:22:27

标签: r data.table

此问题跟随group weighted means上的另一个问题:我想使用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)

使用Roland建议的答案:

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

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

colsToKeep = c("y1980","y1990")

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

我试过

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

但我得到:

Error in x * w : non-numeric argument to binary operator

不确定如何实现我想要的目标。

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

注意,我使用的是data.table包的1.9.3版本。

2 个答案:

答案 0 :(得分:9)

通常情况下,您应该可以:

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

即只是将这些列提供给.SDcols。但目前,这不起作用due to a bug,因为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 列。

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

{{1}}

答案 1 :(得分:0)

我不知道data.table但您是否考虑过使用dplyr?我认为它几乎和data.table

一样快
library(dplyr)
df %>% 
  group_by(region, state, county) %>% 
  summarise(mean_80 = weighted.mean(y1980, weights), 
            mean_90 = weighted.mean(y1990, weights))
Source: local data frame [7 x 5]
Groups: region, state

  region state county   mean_80  mean_90
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