在数据框中按组显示加权平均值

问题描述 投票:0回答:4

有关命令

by
weighted.mean
的问题已经存在,但没有一个能够帮助解决我的问题。我是 R 新手,更习惯数据挖掘语言而不是编程。

我有一个数据框,其中包含每个人(观察/行)的收入、教育水平和样本权重。我想按教育水平计算收入的加权平均值,并且希望将结果与原始数据框架的新列中的每个人相关联,如下所示:

obs income education weight incomegroup
1.   1000      A       10    --> display weighted mean of income for education level A
2.   2000      B        1    --> display weighted mean of income for education level B
3.   1500      B        5    --> display weighted mean of income for education level B
4.   2000      A        2    --> display weighted mean of income for education level A

我尝试过:

data$incomegroup=by(data$education, function(x) weighted.mean(data$income, data$weight))    

它不起作用。加权平均值以某种方式计算并出现在“收入组”列中,但对于整个集合而不是按组或仅针对一组,我不知道。我阅读了有关软件包

plyr
aggregate
的内容,但它似乎没有做我感兴趣的事情。

ave{stats}
命令准确地给出了我正在寻找的内容,但仅用于简单的意思:

data$incomegroup=ave(data$income,data$education,FUN = mean)

不能与配重一起使用。

提前感谢您的帮助!

r weighted-average
4个回答
13
投票

如果我们使用

mutate
,那么我们就可以避免
left_join

library(dplyr)
df %>%
   group_by(education) %>% 
   mutate(weighted_income = weighted.mean(income, weight))
#    obs income education weight weighted_income
#  <int>  <int>    <fctr>  <int>           <dbl>
#1     1   1000         A     10        1166.667
#2     2   2000         B      1        1583.333
#3     3   1500         B      5        1583.333
#4     4   2000         A      2        1166.667

9
投票

尝试使用 dplyr 包,如下所示:

df <- read.table(text = 'obs income education weight   
                          1   1000      A       10     
                          2   2000      B        1     
                          3   1500      B        5     
                          4   2000      A        2', 
                 header = TRUE)     

library(dplyr)

df_summary <- 
  df %>% 
  group_by(education) %>% 
  summarise(weighted_income = weighted.mean(income, weight))

df_summary
# education weighted_income
#     A        1166.667
#     B        1583.333

df_final <- left_join(df, df_summary, by = 'education')

df_final
# obs income education weight weighted_income
#  1   1000         A     10        1166.667
#  2   2000         B      1        1583.333
#  3   1500         B      5        1583.333
#  4   2000         A      2        1166.667

5
投票

基础 R 中有一个函数

weighted.mean
。不幸的是,它不能轻松地与
ave
一起工作。一种解决方案是使用
data.table

library(data.table)
setDT(data)
data[, incomeGroup := weighted.mean(income, weight), by=education]
data
   income education weight incomeGroup
1:   1000         A     10    1166.667
2:   2000         B      1    1583.333
3:   1500         B      5    1583.333
4:   2000         A      2    1166.667

ave
一起使用的奇怪方法是

ave(df[c("income", "weight")], df$education,
    FUN=function(x) weighted.mean(x$income, x$weight))[[1]]
[1] 1166.667 1583.333 1583.333 1166.667

您将子集 data.frame 提供给函数,然后按分组变量进行分组。 FUN 参数创建一个函数,该函数接受 data.frame 并将

weighted.mean
应用于结果。由于最终输出是 data.frame,因此
[[1]]
返回具有所需结果的向量。

请注意,这只是证明这是可能的 - 我不会推荐这种方法,

data.table
技术更干净,并且在大于 1000 个观测值的数据集上速度会更快。


0
投票

这里有基本 R 中的两个选项:

t=read.csv(text="income,education,weight
1000,A,10
2000,B,1
1500,B,5
2000,A,2")

t$incomegroup=with(t,tapply(income*weight,education,sum)/tapply(weight,education,sum))[t$education]

t$incomegroup=sapply(split(t,t$education),\(i)weighted.mean(i$income,i$weight))[t$education]
© www.soinside.com 2019 - 2024. All rights reserved.