【发布时间】:2019-08-06 17:33:30
【问题描述】:
我有两个数据框。我想根据values 数据框中的值计算results 数据框中每一行的加权平均值。 results 的每一行都有两列带有列表。列表的每个可能组合都是values 数据框中的一行。我正在使用下面的代码(两个选项)执行此操作,这可能比我试图解释它更清楚。我想知道的是我是否以及如何对其进行矢量化(我的原始结果数据框非常大)。
library(dplyr)
a = c('a, b, c', 'a, b', 'c')
f = c('p, q', 'r', 's, t')
results <- data.frame(a, f)
# > results
# a f
# 1 a, b, c p, q
# 2 a, b r
# 3 c s, t
av = c('a','b','c')
fv = c('p', 'q', 'r', 's', 't')
values <- expand.grid(av, fv)
values$w <- runif(15)
values$x <- runif(15, min=10, max=100)
# > values
# Var1 Var2 w x
# 1 a p 0.10710168 62.58004
# 2 b p 0.89175147 20.26853
# 3 c p 0.31489520 85.90532
# 4 a q 0.07263807 89.02293
# 5 b q 0.87090293 72.17195
# 6 c q 0.88818599 48.65717
# 7 a r 0.54076274 39.46479
# 8 b r 0.08678314 57.99200
# 9 c r 0.86298554 77.00845
# 10 a s 0.41778402 23.35626
# 11 b s 0.70227865 82.76310
# 12 c s 0.84415123 65.26321
# 13 a t 0.50651689 75.52230
# 14 b t 0.37850063 87.41811
# 15 c t 0.58515251 96.74228
# Option 1 with apply
calc_wa <- function(as, fs){
as <- unlist(strsplit(as, ", "))
fs <- unlist(strsplit(fs, ", "))
valuestokeep <- values %>% filter(Var1 %in% as, Var2 %in% fs)
wa_res <- weighted.mean(valuestokeep$x, valuestokeep$w)
return(wa_res)
}
results$res <- apply(results, 1, function(y) calc_wa(y['a'], y['f']))
# Option 2 with mutate
calc_wa2 <- function(as, fs){
as <- unlist(strsplit(as.character(as), ", "))
fs <- unlist(strsplit(as.character(fs), ", "))
valuestokeep <- values %>% filter(Var1 %in% as, Var2 %in% fs)
wa_res <- weighted.mean(valuestokeep$x, valuestokeep$w)
return(wa_res)
}
results <- results %>% rowwise() %>% mutate(res2= calc_wa2(a, f))
# > results
# Source: local data frame [3 x 4]
# Groups: <by row>
#
# # A tibble: 3 x 4
# a f res res2
# <fct> <fct> <dbl> <dbl>
# 1 a, b, c p, q 52.3 52.3
# 2 a, b r 42.0 42.0
# 3 c s, t 78.2 78.2
(恐怕我缺少一些基本命令,我也不知道如何为问题命名/标记 - 欢迎提出建议)
【问题讨论】:
标签: r dataframe vectorization weighted-average