【问题标题】:Iterative dividing by value specified by multiple dimensions dplyr R迭代除以多维指定的值 dplyr R
【发布时间】:2021-06-25 22:14:18
【问题描述】:

我有一个数据框,其中包含跨多年和跨地区的人口数据。有点像这样:


df <- tibble(YEAR = c("2015", "2015", "2016", "2016", "2017", "2017", "2018", "2018"), 
           LOCATION = c("a", "b", "a", "b", "a", "b", "a", "b"), 
           POPULATION = c(2, 3, 4, 3, 6, 6, 7, 9))

df
# A tibble: 8 x 3
YEAR  LOCATION POPULATION
<chr> <chr>         <dbl>
1 2015  a                 2
2 2015  b                 3
3 2016  a                 4
4 2016  b                 3
5 2017  a                 6
6 2017  b                 6
7 2018  a                 7
8 2018  b                 9

现在,我想计算每个位置相对于第一年的人口(因此 2015 年的人口 = 1)。

实际上,我想将每年的人口除以第一年(或另一个给定年份)的人口。

如果数据只是按年份分组,这将相当简单。我只是打电话给特定的第一年(本报告中的 2015 年)。我会 mutate 并像这样创建我的新变量 RELATIVE_POPULATION = POPULATION/(POPULATION[YEAR == "2015"])

df_year <- df %>%
group_by(YEAR) %>%
summarise(POPULATION = sum(POPULATION)) %>%
mutate(RELATIVE_POPULATION = POPULATION/(POPULATION[YEAR == "2015"]))

df_year

# A tibble: 4 x 3
YEAR  POPULATION RELATIVE_POPULATION
<chr>      <dbl>               <dbl>
1 2015           5                 1  
2 2016           7                 1.4
3 2017          12                 2.4
4 2018          16                 3.2

但我想为每个位置执行此操作,以提供如下所示的输出(因此所有位置 a 的人口除以位置 a 的 2015 年人口,所有位置 b 的人口除以位置 b 的 2015 年人口)

YEAR  LOCATION POPULATION    RELATIVE_POPULATION
<chr> <chr>         <dbl>   <dbl> 
1 2015  a                 2   1
2 2015  b                 3   1
3 2016  a                 4   2
4 2016  b                 3   1
5 2017  a                 6   3
6 2017  b                 6   2
7 2018  a                 7   3.5
8 2018  b                 9   3

我想我可以使用case_when 对每年进行子集计算,但我不知道如何根据其他两个维度为操作指定一个值。我试过了

df_relative <- df %>% 
  mutate(
    RELATIVE_POPULATION = case_when(
      LOCATION == "a" ~ POPULATION/(POPULATION[YEAR == "2015", LOCATION == "a"]),
      LOCATION == "b" ~ POPULATION/(POPULATION[YEAR == "2015", LOCATION == "b"])
    ))

但这会返回错误 Error in POPULATION[YEAR == "2015", LOCATION == "a"] : incorrect number of dimensions

那么这里是否可以指定两个维度,如果可以,如何指定?

一位乐于助人的人(推特上的@MikeMahoney218)巧妙地建议我创建第二个 tibble,其中包含每个位置的 2015 年值,然后我将两者连接在一起,如下所示:

original_pop <- df %>% 
  group_by(LOCATION) %>%
  filter(YEAR == 2015) %>% 
  select(LOCATION, INITIAL_POP = POPULATION)

df %>% 
  left_join(original_pop) %>%
  mutate(RELATIVE_POP = POPULATION / INITIAL_POP)

df
# A tibble: 8 x 5
  YEAR  LOCATION POPULATION INITIAL_POP RELATIVE_POP
  <chr> <chr>         <dbl>       <dbl>        <dbl>
1 2015  a                 2           2          1  
2 2015  b                 3           3          1  
3 2016  a                 4           2          2  
4 2016  b                 3           3          1  
5 2017  a                 6           2          3  
6 2017  b                 6           3          2  
7 2018  a                 7           2          3.5
8 2018  b                 9           3          3  

这可行(耶),但有没有办法在不创建第二个数据框的情况下做到这一点?我可以看到随着代码的增加,这可能会变得复杂。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    按“LOCATION”分组,将“POPULATION”作为子集,YEAR 是 2015 年,然后除以 POPULATION

    library(dplyr)
    df <- df %>% 
        group_by(LOCATION) %>%
        mutate(RELATIVE_POPULATION = POPULATION/POPULATION[YEAR == 2015] ) %>%
        ungroup
    

    -输出

    df
    # A tibble: 8 x 4
      YEAR  LOCATION POPULATION RELATIVE_POPULATION
      <chr> <chr>         <dbl>               <dbl>
    1 2015  a                 2                 1  
    2 2015  b                 3                 1  
    3 2016  a                 4                 2  
    4 2016  b                 3                 1  
    5 2017  a                 6                 3  
    6 2017  b                 6                 2  
    7 2018  a                 7                 3.5
    8 2018  b                 9                 3  
    

    注意:当我们使用== 时,请确保每个“位置”只有一个匹配项,否则,必须获取第一个元素,即match(2015, YEAR)

    【讨论】:

    • 现在我觉得很傻。我想我没有意识到我可以用这种无损方式ungroup!谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 2014-12-21
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    相关资源
    最近更新 更多