Рассчитать разницу между значением меньше первого значения в его группе - PullRequest
3 голосов
/ 25 февраля 2020

У меня есть фрейм данных df, содержащий данные о населении, сгруппированные по городу, полу, году и возрасту:

df <- data.frame(City=c("New York", "New York", "New York", "New York", "New York", 
             "Boston","Boston", "Boston", "Boston"),
             Gender=c("m","m","m", "f","f","m","m","f","f"),
             Year=c("2020","2021", "2022", "2020", "2021","2020","2021", "2020", "2021"),
             Age=c("1","1","1", "2","2","1","1","2","2"),
             Population=c("100", "105","110", "105", "110", "200","201", "220", "222"))

Мне нужно рассчитать для каждой строки разницу с первым значением ее группы (т.е. в 2020 году ) в результате:

df2 <- data.frame(City=c("New York", "New York", "New York", "New York", "New York", "Boston","Boston", "Boston", "Boston"),
              Gender=c("m","m","m", "f","f","m","m","f","f"),
              Year=c("2020","2021", "2022", "2020", "2021","2020","2021", "2020", "2021"),
              Age=c("1","1","1", "2","2","1","1","2","2"),
              Population=c("100", "105","110", "105", "110", "200","201", "220", "222"),
              PopulationGrowth=c("0", "5","10", "0","5","0","1","0","2"))

Спасибо!

Ответы [ 2 ]

4 голосов
/ 25 февраля 2020
df %>%
  group_by(City, Gender) %>%
  arrange(Year, .by_group = T) %>%
  mutate(Population = as.numeric(as.character(Population)),
         PopulationGrowth = Population - first(Population))

# # A tibble: 9 x 6
# # Groups:   City, Gender [4]
#   City     Gender Year  Age   Population PopulationGrowth
#   <fct>    <fct>  <fct> <fct>      <dbl>            <dbl>
# 1 Boston   f      2020  2            220                0
# 2 Boston   f      2021  2            222                2
# 3 Boston   m      2020  1            200                0
# 4 Boston   m      2021  1            201                1
# 5 New York f      2020  2            105                0
# 6 New York f      2021  2            110                5
# 7 New York m      2020  1            100                0
# 8 New York m      2021  1            105                5
# 9 New York m      2022  1            110               10

arrange меняет порядок строк. Если вы хотите сохранить первоначальный порядок, попробуйте это:

df %>%
  group_by(City, Gender) %>%
  mutate(Population = as.numeric(as.character(Population)),
         PopulationGrowth = Population - first(Population, order_by = order(Year)))

# # A tibble: 9 x 6
# # Groups:   City, Gender [4]
#   City     Gender Year  Age   Population PopulationGrowth
#   <fct>    <fct>  <fct> <fct>      <dbl>            <dbl>
# 1 New York m      2020  1            100                0
# 2 New York m      2021  1            105                5
# 3 New York m      2022  1            110               10
# 4 New York f      2020  2            105                0
# 5 New York f      2021  2            110                5
# 6 Boston   m      2020  1            200                0
# 7 Boston   m      2021  1            201                1
# 8 Boston   f      2020  2            220                0
# 9 Boston   f      2021  2            222                2
0 голосов
/ 25 февраля 2020

Вот базовое решение R с использованием ave

df2 <- within(df,PopulationGrowth <- ave(as.numeric(as.character(Population)),City,Gender, FUN = function(v) v-head(v,1)))

, такое что

> df2
      City Gender Year Age Population PopulationGrowth
1 New York      m 2020   1        100                0
2 New York      m 2021   1        105                5
3 New York      m 2022   1        110               10
4 New York      f 2020   2        105                0
5 New York      f 2021   2        110                5
6   Boston      m 2020   1        200                0
7   Boston      m 2021   1        201                1
8   Boston      f 2020   2        220                0
9   Boston      f 2021   2        222                2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...