R Как разбить данные на группы - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть следующий набор данных:

Name  Year  VarA  VarB Data.1  Data.2
A     2016  L     H    100     101
A     2017  L     H    105     99
A     2018  L     H    103     105
A     2016  L     A    90      95
A     2017  L     A    99      92
A     2018  L     A    102     101

Я хочу добавить отстающую переменную по группировке: Name, VarA, VarB, чтобы мои данные выглядели так:

Name  Year  VarA  VarB Data.1  Data.2  Lg1.Data.1 Lg2.Data.1
A     2016  L     H    100     101     NA        NA
A     2017  L     H    105     99      100       NA
A     2018  L     H    103     105     105       100
A     2016  L     A    90      95      NA        NA
A     2017  L     A    99      92      90        NA
A     2018  L     A    102     101     99        90

Я нашел следующую ссылку, которая полезна: отладка: функция для создания нескольких лагов для нескольких столбцов (dplyr)

И я использую следующий код:

df <- df %>% 
  group_by(Name) %>% 
  arrange(Name, VarA, VarB, Year) %>% 
  do(data.frame(., setNames(shift(.[,c(5:6)], 1:2), c(seq(1:8)))))

Однако отставание компенсирует все данные, связанные с именем / именем, вместо группировки, которую я хочу, поэтому только 2018 лет точно отстают.

Name  Year  VarA  VarB Data.1  Data.2  Lg1.Data.1 Lg2.Data.1
A     2016  L     H    100     101     NA        NA
A     2017  L     H    105     99      100       NA
A     2018  L     H    103     105     105       100
A     2016  L     A    90      95      103       105
A     2017  L     A    99      92      90        103
A     2018  L     A    102     101     99        90

Как получить задержку сброса для каждой новой комбинации группировки (например, Имя / VarA / VarB)?

1 Ответ

0 голосов
/ 07 декабря 2018

dplyr::lag позволяет установить расстояние, на которое вы хотите отставать.Вы можете группировать по любым переменным, которые вы хотите - в данном случае, Name, VarA и VarB - перед созданием ваших отстающих переменных.

library(dplyr)

df %>%
  group_by(Name, VarA, VarB) %>%
  mutate(Lg1.Data.1 = lag(Data.1, n = 1), Lg2.Data.1 = lag(Data.1, n = 2))
#> # A tibble: 6 x 8
#> # Groups:   Name, VarA, VarB [2]
#>   Name   Year VarA  VarB  Data.1 Data.2 Lg1.Data.1 Lg2.Data.1
#>   <chr> <dbl> <chr> <chr>  <dbl>  <dbl>      <dbl>      <dbl>
#> 1 A      2016 L     H        100    101         NA         NA
#> 2 A      2017 L     H        105     99        100         NA
#> 3 A      2018 L     H        103    105        105        100
#> 4 A      2016 L     A         90     95         NA         NA
#> 5 A      2017 L     A         99     92         90         NA
#> 6 A      2018 L     A        102    101         99         90

Если вы хотите версию, которая масштабируется до большегоlags, вы можете использовать нестандартную оценку для динамического создания новых столбцов с задержками.Я сделаю это с purrr::map, чтобы выполнить итерацию набора n для отставания, составить список фреймов данных с добавленными новыми столбцами, а затем соединить все фреймы данных вместе.Вероятно, есть более эффективные способы сделать это в NSE, так что, надеюсь, кто-то сможет улучшить это.

Я собираю некоторые новые данные, просто для иллюстрации более широкого диапазона лет.Внутри mutate вы можете создавать имена столбцов с помощью quo_name.

library(dplyr)
library(purrr)

set.seed(127)
df <- tibble(
  Name = "A", Year = rep(2016:2020, 2), VarA = "L", VarB = rep(c("H", "A"), each = 5),
  Data.1 = sample(1:10, 10, replace = T), Data.2 = sample(1:10, 10, replace = T) 
)

df_list <- purrr::map(1:4, function(i) {
  df %>%
    group_by(Name, VarA, VarB) %>%
    mutate(!!quo_name(paste0("Lag", i)) := dplyr::lag(Data.1, n = i))
})

Вам не нужно сохранять этот список - я просто делаю это, чтобы показать пример одного из фреймов данных,Вместо этого вы можете перейти прямо к reduce.

df_list[[3]]
#> # A tibble: 10 x 7
#> # Groups:   Name, VarA, VarB [2]
#>    Name   Year VarA  VarB  Data.1 Data.2  Lag3
#>    <chr> <int> <chr> <chr>  <int>  <int> <int>
#>  1 A      2016 L     H          3      9    NA
#>  2 A      2017 L     H          1      4    NA
#>  3 A      2018 L     H          3      8    NA
#>  4 A      2019 L     H          2      2     3
#>  5 A      2020 L     H          4      5     1
#>  6 A      2016 L     A          8      4    NA
#>  7 A      2017 L     A          6      8    NA
#>  8 A      2018 L     A          3      2    NA
#>  9 A      2019 L     A          8      6     8
#> 10 A      2020 L     A          9      1     6

Затем использовать purrr::reduce, чтобы объединить все кадры данных в списке.Поскольку в каждом из фреймов данных есть одинаковые столбцы, к которым вы хотите присоединиться, вы можете обойтись без указания столбцов присоединения в inner_join.

reduce(df_list, inner_join)
#> Joining, by = c("Name", "Year", "VarA", "VarB", "Data.1", "Data.2")
#> Joining, by = c("Name", "Year", "VarA", "VarB", "Data.1", "Data.2")
#> Joining, by = c("Name", "Year", "VarA", "VarB", "Data.1", "Data.2")
#> # A tibble: 10 x 10
#> # Groups:   Name, VarA, VarB [?]
#>    Name   Year VarA  VarB  Data.1 Data.2  Lag1  Lag2  Lag3  Lag4
#>    <chr> <int> <chr> <chr>  <int>  <int> <int> <int> <int> <int>
#>  1 A      2016 L     H          3      9    NA    NA    NA    NA
#>  2 A      2017 L     H          1      4     3    NA    NA    NA
#>  3 A      2018 L     H          3      8     1     3    NA    NA
#>  4 A      2019 L     H          2      2     3     1     3    NA
#>  5 A      2020 L     H          4      5     2     3     1     3
#>  6 A      2016 L     A          8      4    NA    NA    NA    NA
#>  7 A      2017 L     A          6      8     8    NA    NA    NA
#>  8 A      2018 L     A          3      2     6     8    NA    NA
#>  9 A      2019 L     A          8      6     3     6     8    NA
#> 10 A      2020 L     A          9      1     8     3     6     8

Создано в 2018-12-07 пакетом Представить (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...