按组折叠数据框,使用变量列表进行加权平均和求和
Collapse data frame, by group, using lists of variables for weighted average AND sum
我想根据组折叠以下数据框,同时使用求和和加权平均值。
我有以下数据框
group_id = c(1,1,1,2,2,3,3,3,3,3)
var_1 = sample.int(20, 10)
var_2 = sample.int(20, 10)
var_percent_1 =rnorm(10,.5,.4)
var_percent_2 =rnorm(10,.5,.4)
weighting =sample.int(50, 10)
df_to_collapse = data.frame(group_id,var_1,var_2,var_percent_1,var_percent_2,weighting)
我想根据 group_id
确定的组折叠我的数据。但是,在我的数据中,我有绝对水平 (var_1
、var_2
) 和百分比 (var_percent_1
、var_percent_2
) 的变量。
我为每种类型的变量创建了两个列表(我的真实数据要大得多,所以这是必要的)。我还有一个加权变量(weighting
)。
to_be_weighted =df_to_collapse[, 4:5]
to_be_summed = df_to_collapse[,2:3]
to_be_weighted_2=colnames(to_be_weighted)
to_be_summed_2=colnames(to_be_summed)
我的目标是根据变量的类型(即,如果以百分比表示,我使用加权平均值)同时使用总和或加权平均值来折叠我的数据。
这是我最好的尝试:
df_to_collapse %>% group_by(group_id) %>% summarise_at(.vars = c(to_be_summed_2,to_be_weighted_2), .funs=c(sum, mean))
但是,如您所见,它不是 加权平均值
我尝试了很多不同的方法来使用 weighted.mean
函数,但都没有成功。这是一个这样的尝试的例子;
df_to_collapse %>% group_by(group_id) %>% summarise_at(.vars = c(to_be_weighted_2,to_be_summed_2), .funs=c(weighted.mean(to_be_weighted_2, weighting), sum))
以及对应的错误:
Error in weighted.mean.default(to_be_weighted_2, weighting) :
'x' and 'w' must have the same length
这是一种方法,通过重塑为长数据,添加一个名为 type
的虚拟变量来确定它是否是百分比(可选,但很方便),在 summarise
中应用一个函数基于无论是百分比,然后传播回宽形状。如果您可以更改列名,您可以想出一种更优雅的方式来处理 type
列,但这实际上是为了方便。
我的诀窍是 type[1] == "percent"
;我不得不使用 [1]
因为每个组中的所有内容都具有相同的类型,但除此之外 ==
对向量中的每个值进行操作并给出多个逻辑值,当你真的只需要 1.
library(tidyverse)
set.seed(1234)
group_id = c(1,1,1,2,2,3,3,3,3,3)
var_1 = sample.int(20, 10)
var_2 = sample.int(20, 10)
var_percent_1 =rnorm(10,.5,.4)
var_percent_2 =rnorm(10,.5,.4)
weighting =sample.int(50, 10)
df_to_collapse <- data.frame(group_id,var_1,var_2,var_percent_1,var_percent_2,weighting)
df_to_collapse %>%
gather(key = var, value = value, -group_id, -weighting) %>%
mutate(type = ifelse(str_detect(var, "percent"), "percent", "int")) %>%
group_by(group_id, var) %>%
summarise(sum_or_avg = ifelse(type[1] == "percent", weighted.mean(value, weighting), sum(value))) %>%
ungroup() %>%
spread(key = var, value = sum_or_avg)
#> # A tibble: 3 x 5
#> group_id var_1 var_2 var_percent_1 var_percent_2
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 26 31 0.269 0.483
#> 2 2 32 21 0.854 0.261
#> 3 3 29 49 0.461 0.262
由 reprex package (v0.2.0) 创建于 2018-05-04。
我想根据组折叠以下数据框,同时使用求和和加权平均值。
我有以下数据框
group_id = c(1,1,1,2,2,3,3,3,3,3)
var_1 = sample.int(20, 10)
var_2 = sample.int(20, 10)
var_percent_1 =rnorm(10,.5,.4)
var_percent_2 =rnorm(10,.5,.4)
weighting =sample.int(50, 10)
df_to_collapse = data.frame(group_id,var_1,var_2,var_percent_1,var_percent_2,weighting)
我想根据 group_id
确定的组折叠我的数据。但是,在我的数据中,我有绝对水平 (var_1
、var_2
) 和百分比 (var_percent_1
、var_percent_2
) 的变量。
我为每种类型的变量创建了两个列表(我的真实数据要大得多,所以这是必要的)。我还有一个加权变量(weighting
)。
to_be_weighted =df_to_collapse[, 4:5]
to_be_summed = df_to_collapse[,2:3]
to_be_weighted_2=colnames(to_be_weighted)
to_be_summed_2=colnames(to_be_summed)
我的目标是根据变量的类型(即,如果以百分比表示,我使用加权平均值)同时使用总和或加权平均值来折叠我的数据。
这是我最好的尝试:
df_to_collapse %>% group_by(group_id) %>% summarise_at(.vars = c(to_be_summed_2,to_be_weighted_2), .funs=c(sum, mean))
但是,如您所见,它不是 加权平均值
我尝试了很多不同的方法来使用 weighted.mean
函数,但都没有成功。这是一个这样的尝试的例子;
df_to_collapse %>% group_by(group_id) %>% summarise_at(.vars = c(to_be_weighted_2,to_be_summed_2), .funs=c(weighted.mean(to_be_weighted_2, weighting), sum))
以及对应的错误:
Error in weighted.mean.default(to_be_weighted_2, weighting) :
'x' and 'w' must have the same length
这是一种方法,通过重塑为长数据,添加一个名为 type
的虚拟变量来确定它是否是百分比(可选,但很方便),在 summarise
中应用一个函数基于无论是百分比,然后传播回宽形状。如果您可以更改列名,您可以想出一种更优雅的方式来处理 type
列,但这实际上是为了方便。
我的诀窍是 type[1] == "percent"
;我不得不使用 [1]
因为每个组中的所有内容都具有相同的类型,但除此之外 ==
对向量中的每个值进行操作并给出多个逻辑值,当你真的只需要 1.
library(tidyverse)
set.seed(1234)
group_id = c(1,1,1,2,2,3,3,3,3,3)
var_1 = sample.int(20, 10)
var_2 = sample.int(20, 10)
var_percent_1 =rnorm(10,.5,.4)
var_percent_2 =rnorm(10,.5,.4)
weighting =sample.int(50, 10)
df_to_collapse <- data.frame(group_id,var_1,var_2,var_percent_1,var_percent_2,weighting)
df_to_collapse %>%
gather(key = var, value = value, -group_id, -weighting) %>%
mutate(type = ifelse(str_detect(var, "percent"), "percent", "int")) %>%
group_by(group_id, var) %>%
summarise(sum_or_avg = ifelse(type[1] == "percent", weighted.mean(value, weighting), sum(value))) %>%
ungroup() %>%
spread(key = var, value = sum_or_avg)
#> # A tibble: 3 x 5
#> group_id var_1 var_2 var_percent_1 var_percent_2
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 26 31 0.269 0.483
#> 2 2 32 21 0.854 0.261
#> 3 3 29 49 0.461 0.262
由 reprex package (v0.2.0) 创建于 2018-05-04。