【问题标题】:Create a new variable and assign the value to a group创建一个新变量并将值分配给一个组
【发布时间】:2018-10-05 19:39:34
【问题描述】:

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

欢迎提出任何建议。

谢谢

马诺洛

【问题讨论】:

  • 如果与组一起工作,您不想引用整个数据集,因此请在解决方案中的任何地方取出 df$ 并直接引用变量名称。然后我认为它可以按您的意愿工作(如果 1.25 真的应该是 1.33)。您可以使用sum(age.cat %in% c(1, 3))/sum(age.cat == 2) 简化一些事情,但这不是必需的。
  • @aosmith 谢谢你,在我删除'df$'后它工作得很好。也感谢您建议使用“sum”的更轻量级的代码。

标签: r grouping tidyverse dplyr


【解决方案1】:

这里有一个选项:

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 分组并获得完整的列。

【讨论】:

  • 谢谢@iod 我也试过你的代码,但我收到一条错误消息 Error in summarise(., n = n()) : argument "by" is missing, with no default 。我查看了 n() 的文档,但在其论点中找不到任何内容。在您建议放弃 df$ 之后,dplyr 管道终于工作了,但我也有兴趣观看您建议的代码工作。
  • 有可能汇总或 n 被另一个包掩盖。尝试在两者之前输入 dplyr::。代码按原样对我有用...
  • 尝试看看冲突()给你什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
相关资源
最近更新 更多