创建一个新变量并将值分配给组

时间:2018-10-05 19:39:34

标签: r grouping tidyverse mutate

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

> 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::mutatedplyr::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,但没有任何运气。

欢迎任何建议。

谢谢

Manolo

1 个答案:

答案 0 :(得分:0)

这是一个选择:

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.id等,就可以绕过tidyverse分组并获得完整的列。