根据上一行的值在R中的tibble中创建多个新列,为所有列提供前缀



我有一个这样的tibble:

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

我想创建一个新的tibble,在那里我想落后一些。我想创建名为prev+lagged_col_name的新列,例如prev_a。在我的实际数据中,有很多cols,所以我不想手动写出来。另外,我只想做几个星期。在这个例子中,我已经手动完成了,但想知道是否有一种方法可以使用一个功能来完成。

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

谢谢你的帮助!

在当前的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

由reprex包于2020-04-29创建(v0.3.0(

你可以这样做

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()函数。

请参阅文档中的一些示例,而不是您想要的lagmean

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))

最新更新