首页 > 解决方案 > 通过根据分组数据中的条件减去行来创建新变量

问题描述

我有该国每个人口普查区在三个时间点(2000 年、2013 年、2019 年)的数据,这些数据由 CBSA 分组。我正在尝试创建一个名为 cont_chg_pedu_colplus 的新变量,它是 pedu_colplus 的 2013 年和 2000 年值之间的差异。因此,在下面的示例中,我想创建一个名为 cont_chg_pedu_colplus 的新列,它返回值 3.0 (14.6 - 11.6)。理想情况下,每组区域都具有相同的值,因为我只对时间 1 和时间 2 之间的差异感兴趣。

  tractid      year CBSA_name   pedu_colplus
  <chr>       <dbl> <chr>              <dbl>
1 48059030101  2000 Abilene, TX         11.6
2 48059030101  2013 Abilene, TX         14.6
3 48059030101  2019 Abilene, TX         20.6
4 48059030102  2000 Abilene, TX         11.6
5 48059030102  2013 Abilene, TX         14.2
6 48059030102  2019 Abilene, TX         20.2

以下是我到目前为止的代码。我认为它会引发以下错误,因为我只在一年内进行子集化(37 行而不是数据集中的 111 行)。我不想让我的数据变宽,因为我还有很多其他的数据操作必须要做。我不能迟到上班。


gent_vars_prelim <- outcome_data %>% 
    
  mutate(cont_chg_pedu_colplus = pedu_colplus[year == 2013] - pedu_colplus[year == 2000], na.rm = TRUE) %>%
                
  glimpse()

mutate()输入问题cont_chg_pedu_colplus。x 输入cont_chg_pedu_colplus无法回收到大小 37。ℹ 输入cont_chg_pedu_colpluspedu_colplus[year == 2013] - pedu_colplus[year == 2000]. ℹ 输入cont_chg_pedu_colplus的大小必须是 37 或 1,而不是 0。 ℹ 第 1 组出现错误:CBSA_name = "Abilene, TX", year = 2000

有什么想法吗?谢谢。

标签: rtidyversedplyr

解决方案


我假设对于每一对唯一的tractidand CBSA_name,最多有 3 个条目(可能的值 2000、2013 或 2019),并且对于给定的一对and year,没有两年是相同的。tractidCBSA_name

首先,我们将通过tractid和对数据框中的值进行分组CBSA_name。每组最多有 3 行,每年一个。我们使用dplyr::group_by(tractid, CBSA_name).

接下来,我们将强制该组拥有全部 3 年。我们tidyr::complete(year = c(2000, 2013, 2019))按照您在评论中的建议执行此操作。(这比我使用的评论要好filter(n() == 3),因为我们实际上不在乎是否只有 2019 年丢失,并且我们能够保留不完整的组。)

然后,我们可以计算出您感兴趣的结果:dplyr::mutate(cont_chg_pedu_colplus = pedu_colplus[year == 2013] - pedu_colplus[year == 2000]). 我们只需要dplyr::ungroup()在这之后就完成了。

最终代码:

gent_vars_prelim <- outcome_data %>%
  dplyr::group_by(tractid, CBSA_name) %>%
  tidyr::complete(year = c(2000, 2013, 2019)) %>%
  dplyr::mutate(cont_chg_pedu_colplus = pedu_colplus[year == 2013] - pedu_colplus[year == 2000]) %>%
  dplyr::ungroup() %>%
  glimpse()

测试用例:

outcome_data <- data.frame(tractid = c(48059030101, 48059030101, 48059030101, 48059030101, 48059030101, 48059030101, 48059030102, 48059030102, 48059030102, 48059030103),
                           year = c(2000, 2013, 2019, 2000, 2013, 2019, 2000, 2013, 2019, 2000),
                           CBSA_name = c("Abilene, TX", "Abilene, TX", "Abilene, TX", "Austin, TX", "Austin, TX", "Austin, TX", "Abilene, TX", "Abilene, TX", "Abilene, TX", "Abilene, TX"),
                           pedu_colplus = c(11.6, 14.6, 20.6, 8.4, 9.0, 9.6, 11.6, 14.2, 20.2, 4.0))

结果:

> tibble(gent_vars_prelim)
# A tibble: 12 x 1
   gent_vars_prelim$tractid $CBSA_name  $year $pedu_colplus $cont_chg_pedu_colplus
                      <dbl> <fct>       <dbl>         <dbl>                  <dbl>
 1              48059030101 Abilene, TX  2000          11.6                  3    
 2              48059030101 Abilene, TX  2013          14.6                  3    
 3              48059030101 Abilene, TX  2019          20.6                  3    
 4              48059030101 Austin, TX   2000           8.4                  0.600
 5              48059030101 Austin, TX   2013           9                    0.600
 6              48059030101 Austin, TX   2019           9.6                  0.600
 7              48059030102 Abilene, TX  2000          11.6                  2.60 
 8              48059030102 Abilene, TX  2013          14.2                  2.60 
 9              48059030102 Abilene, TX  2019          20.2                  2.60 
10              48059030103 Abilene, TX  2000           4                   NA    
11              48059030103 Abilene, TX  2013          NA                   NA    
12              48059030103 Abilene, TX  2019          NA                   NA    

推荐阅读