Создать несколько новых столбцов в Tibble в R на основе значения предыдущей строки, давая префикс всем - PullRequest
1 голос
/ 29 апреля 2020

У меня есть тиббл так:

df <- tibble(a = seq(1:10),
         b = seq(21,30),
         c = seq(31,40))

Я хочу создать новый тиббл, где я хочу немного отстать. Я хочу создать новые столбцы с именем prev + lagged_col_name, например prev_a. В моих реальных данных есть много столбцов, поэтому я не хочу выписывать их вручную. Кроме того, я хочу сделать это только для некоторых cols. Например, я сделал это вручную, но хотел знать, есть ли способ использовать функцию для этого.

 df_new <- df %>%
  mutate(prev_a = lag(a),
         prev_b = lag(b),
         prev_d = lag(d))

Спасибо за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 29 апреля 2020

С текущей версией dplyr вы можете создавать новые имена переменных с помощью mutate_at, используя именованный список, в качестве суффикса будет использоваться имя списка. Если вы хотите использовать его в качестве префикса, как в вашем примере, вы можете использовать rename_at для исправления именования переменных. С вашими реальными данными вам нужно отрегулировать выбор vars(). Для вашего примера данные matches("[a-c]") сработали.

library(dplyr)
df <- tibble(a = seq(1:10),
             b = seq(21,30),
             c = seq(31,40))
df %>% 
  mutate_at(vars(matches("[a-c]")), list(prev = ~ lag(.x))) 
#> # A tibble: 10 x 6
#>        a     b     c a_prev b_prev c_prev
#>    <int> <int> <int>  <int>  <int>  <int>
#>  1     1    21    31     NA     NA     NA
#>  2     2    22    32      1     21     31
#>  3     3    23    33      2     22     32
#>  4     4    24    34      3     23     33
#>  5     5    25    35      4     24     34
#>  6     6    26    36      5     25     35
#>  7     7    27    37      6     26     36
#>  8     8    28    38      7     27     37
#>  9     9    29    39      8     28     38
#> 10    10    30    40      9     29     39

df %>% 
  mutate_at(vars(matches("[a-c]")), list(prev = ~ lag(.x))) %>% 
  rename_at(vars(contains( "_prev") ), list( ~paste("prev", gsub("_prev", "", .), sep = "_")))
#> # A tibble: 10 x 6
#>        a     b     c prev_a prev_b prev_c
#>    <int> <int> <int>  <int>  <int>  <int>
#>  1     1    21    31     NA     NA     NA
#>  2     2    22    32      1     21     31
#>  3     3    23    33      2     22     32
#>  4     4    24    34      3     23     33
#>  5     5    25    35      4     24     34
#>  6     6    26    36      5     25     35
#>  7     7    27    37      6     26     36
#>  8     8    28    38      7     27     37
#>  9     9    29    39      8     28     38
#> 10    10    30    40      9     29     39

Создано в 2020-04-29 пакетом Представить (v0.3.0)

1 голос
/ 29 апреля 2020

Вы можете сделать это следующим образом

df_new <- bind_cols(
 df,
 df %>% mutate_at(.vars = vars("a","b","c"), function(x) lag(x))
)

Имена немного неприятны, но вы можете переименовать их отметьте здесь . Или посмотрите комментарий @Bas, чтобы получить имена с суффиксом.

# A tibble: 10 x 6
       a     b     c    a1    b1    c1
   <int> <int> <int> <int> <int> <int>
 1     1    21    31    NA    NA    NA
 2     2    22    32     1    21    31
 3     3    23    33     2    22    32
 4     4    24    34     3    23    33
 5     5    25    35     4    24    34
 6     6    26    36     5    25    35
 7     7    27    37     6    26    36
 8     8    28    38     7    27    37
 9     9    29    39     8    28    38
10    10    30    40     9    29    39

Если у вас dplyr 1.0, вы можете использовать новую функцию accross().

См. Некоторые примеры из документов, вместо mean вы хотите lag

df %>% mutate_if(is.numeric, mean, na.rm = TRUE)
# ->
df %>% mutate(across(is.numeric, mean, na.rm = TRUE))

df %>% mutate_at(vars(x, starts_with("y")), mean, na.rm = TRUE)
# ->
df %>% mutate(across(c(x, starts_with("y")), mean, na.rm = TRUE))

df %>% mutate_all(mean, na.rm = TRUE)
# ->
df %>% mutate(across(everything(), mean, na.rm = TRUE))

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