#r #dplyr
Вопрос:
У меня есть фрейм данных, который включает данные о населении за несколько лет и географические данные. Выглядит примерно так:
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 в Twitter) хитро предложил мне создать второй 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
Это работает (да), но есть ли способ сделать это без создания второго фрейма данных? Я видел, что это может усложняться по мере умножения кода.
Ответ №1:
Создайте группу по «МЕСТОПОЛОЖЕНИЮ», подмножеству «НАСЕЛЕНИЕ», где YEAR
находится 2015 год, и разделите НАСЕЛЕНИЕ
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)
Комментарии:
1. Ну а теперь я чувствую себя очень глупо. Я не думаю, что раньше осознавал, что могу
ungroup
так без потерь! Спасибо