首页 > 解决方案 > 创建一个新变量并将值分配给一个组

问题描述

我有 65524 个观察值,其中一个变量是一个家庭的 ID,另一个是1如果家庭中的人的年龄小于 15 岁,则分配值的因素,2如果年龄是年龄在 15 至 64岁之间,3如果该人的年龄为 65 岁或以上,则被分配。小标题看起来像这样

> head(df, 15)
# A tibble: 15 x 2
   hh.id age.cat  
   <dbl> <dbl+lbl>
 1 11009 2        
 2 11009 2        
 3 11009 2        
 4 11009 2        
 5 11009 2        
 6 11009 1        
 7 11009 1        
 8 11009 1        
 9 11018 2        
10 11018 1        
11 11018 1        
12 11018 1        
13 11018 1        
14 11018 2        
15 11018 2

我需要创建一个变量来估计每个家庭的抚养比。类似的东西

 > head(df, 15)
# A tibble: 15 x 3
   hh.id age.cat  dep.ratio
   <dbl> <dbl+lbl><dbl>
 1 11009 2        0.60
 2 11009 2        0.60
 3 11009 2        0.60
 4 11009 2        0.60
 5 11009 2        0.60
 6 11009 1        0.60
 7 11009 1        0.60
 8 11009 1        0.60
 9 11018 2        1.25
10 11018 1        1.25
11 11018 1        1.25
12 11018 1        1.25
13 11018 1        1.25
14 11018 2        1.25
15 11018 2        1.25

我认为使用dplyr::mutate并且dplyr::group_by会起作用

df <- df %>%
  dplyr::group_by(hh.id) %>%
  dplyr::mutate(dep.ratio = (length(which(df$age.cat == 1)) + length(which(df$age.cat == 3)))/length(which(df$age.cat == 2)))

但是,我没有得到每个组(即每个家庭)的估计值,但我得到了整个样本的总体抚养比,每次观察都重复。

# A tibble: 15 x 3
# Groups:   hh.id [2]
   hh.id age.cat   dep.ratio
   <dbl> <dbl+lbl>     <dbl>
 1 11009 2              1.02
 2 11009 2              1.02
 3 11009 2              1.02
 4 11009 2              1.02
 5 11009 2              1.02
 6 11009 1              1.02
 7 11009 1              1.02
 8 11009 1              1.02
 9 11018 2              1.02
10 11018 1              1.02
11 11018 1              1.02
12 11018 1              1.02
13 11018 1              1.02
14 11018 2              1.02
15 11018 2              1.02

然后我考虑使用tapply,但我无法编写一个以 的值为条件的函数hh.id。最后,我也尝试过aggregate,但没有任何运气。

欢迎任何建议。

谢谢

马诺洛

标签: rgroupingtidyversedplyr

解决方案


这是一个选项:

ratiodf<- df %>% group_by(hh.id,age.cat) %>% 
  summarize(n=n()) %>% 
  spread(age.cat,n) %>% 
  mutate(ratio=(`1`+`3`)/`2`)

这会给你这样的东西:

# A tibble: 2 x 4
# Groups:   hh.id [2]
  hh.id   `1`   `2` ratio
  <int> <int> <int> <dbl>
1 11009     3     5  0.6 
2 11018     4     3  1.33

如果您需要保留原始 df 中的数据(例如,其他列),您可以继续使用 left_join:

left_join(df, ratiodf[,c(-2:-3)], by="hh.id")

这将导致:

   hh.id age.cat    ratio
1  11009       2 0.600000
2  11009       2 0.600000
3  11009       2 0.600000
4  11009       2 0.600000
5  11009       2 0.600000
6  11009       1 0.600000
7  11009       1 0.600000
8  11009       1 0.600000
9  11018       2 1.333333
10 11018       1 1.333333
11 11018       1 1.333333
12 11018       1 1.333333
13 11018       1 1.333333
14 11018       2 1.333333
15 11018       2 1.333333

您的代码不起作用的原因是,一旦您输入df$hh.idetc. 的基本格式,您就会绕过 tidyverse 分组并获得完整的列。


推荐阅读