#r #tidyverse
Вопрос:
У меня есть большой фрейм данных со многими значениями и одним весом. Я хотел бы рассчитать средневзвешенное значение многих переменных, используя этот один вес, и я пытаюсь найти эффективный код для этого.
В качестве примера предположим, что у меня есть следующий фрейм данных:
library(stringi)
set.seed(200)
df <- cbind.data.frame(id = stri_rand_strings(6, 3, pattern = "[A-Za-z0-9]"),
year = 2005 ,
australia = runif(6, min=0, max=100) ,
austria = runif(6, min=0, max=100) ,
weight = runif(6, min=0, max=100) )
дающий
id year australia austria weight
1 Xaa 2005 92.217757 31.942681 26.37486
2 gfq 2005 64.632962 26.532429 16.60537
3 i5W 2005 46.036069 71.736956 48.30747
4 ESe 2005 9.874701 38.033536 32.57277
5 9eN 2005 20.659381 3.062094 92.53639
6 JZ8 2005 92.233983 52.141938 56.05588
Я хотел бы рассчитать средневзвешенное значение каждой переменной с названиями стран с указанием веса. Я мог бы, конечно, рассчитать это, используя :
weighted.mean(df$australia , df$weight)
weighted.mean(df$austria , df$weight)
но это было бы чрезвычайно громоздко при наличии более 30 переменных такого value
типа. Есть ли способ автоматизировать это?
Комментарии:
1. У вас есть конкретные колонки? Есть ли способ их индексировать? то
df[, 3:4]
есть, например?
Ответ №1:
Ты имеешь в виду вот так?
dplyr
library(dplyr)
mycols <- c("australia", "austria")
df %>%
# mutate(across(mycols, list(wavg = ~ weighted.mean(., weight))))
id year australia austria weight australia_wavg austria_wavg
# 1 Xaa 2005 92.2178 31.9427 26.375 48.203 33.744
# 2 gfq 2005 64.6330 26.5324 16.605 48.203 33.744
# 3 i5W 2005 46.0361 71.7370 48.307 48.203 33.744
# 4 ESe 2005 9.8747 38.0335 32.573 48.203 33.744
# 5 9eN 2005 20.6594 3.0621 92.536 48.203 33.744
# 6 JZ8 2005 92.2340 52.1419 56.056 48.203 33.744
или резюмируя это с
df %>%
summarize(across(mycols, list(wavg = ~ weighted.mean(., weight))))
# australia_wavg austria_wavg
# 1 48.203 33.744
основание R
mycols <- c("australia", "austria")
lapply(subset(df, select = mycols), weighted.mean, df$weight)
# $australia
# [1] 48.203
# $austria
# [1] 33.744
Комментарии:
1. Приношу свои извинения, я забыл упомянуть, что имена каждой переменной являются названиями стран
2. Ваш код не будет работать, если имена переменных имеют другой шаблон
3. Разве вы заранее не знаете названия столбцов? Если вы это сделаете, то ваш вопрос спорен, используйте
dplyr::one_of
вместоstarts_with
илиselect=c(myvars)
в базе R.4. Смотрите мою правку, в ней больше не используются ваши
value*
имена.
Ответ №2:
Вы можете использовать любое из следующих:
> colSums(df[, 3:4] * prop.table(df[, 'weight']))
australia austria
48.20293 33.74373
> sapply(df[, 3:4], weighted.mean, df[, 'weight'])
australia austria
48.20293 33.74373