Средневзвешенное значение для нескольких столбцов по группам (в таблице данных).

Этот вопрос следует за другим вопросом о средневзвешенных значениях группы: я хотел бы создать взвешенные средние значения внутри группы, используя 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)

Используя предложенный Роландом ответ на вышеупомянутый вопрос:

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.

Я старался

 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 были сохранены оригинальные имена столбцов.

Примечание: я использую версию 1.9.3 пакета data.table.

2 ответа

Решение

Обычно вы должны уметь:

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

т.е. просто предоставляя только эти столбцы .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

Я не знаю 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
Другие вопросы по тегам