Mutate_All Except Some Columns

Mutate_All Except Some Columns

I have a dataframe containing a set of variables that I want to lag at different lenghts so that I can use them in regressions later on (instead of lagging one variable at a time manually).

I found this code on Stackoverflow that seems to do the trick:

df = data.frame(a = 1:10, b = 21:30)
dplyr::mutate_all(df, lag)
    a  b
1  NA NA
2   1 21
3   2 22
4   3 23
5   4 24
6   5 25
7   6 26
8   7 27
9   8 28
10  9 29

The problem is that this lags every column and I have some columns that I don't want to be lagged. How do I adapt the above code so that the columns I don't want to be lagged are excluded? And also how do i lag a different lenghts, now it only lags by 1 as the default setting

2 Answers

I keep googling up this same Q&A and then noting that mutate_at() and mutate_if() are now superceded by across(), which provides a slightly easier-to-remember approach for the "mutate all except these columns" pattern

df = data.frame(a = 1:10, b = 21:30, c=31:40, d=41:50)
> df
    a  b  c  d
1   1 21 31 41
2   2 22 32 42
3   3 23 33 43
4   4 24 34 44
5   5 25 35 45
6   6 26 36 46
7   7 27 37 47
8   8 28 38 48
9   9 29 39 49
10 10 30 40 50
> # everythng but columns b and c
> df %>% mutate(across(!b & !c, lag))
    a  b  c  d
1  NA 21 31 NA
2   1 22 32 41
3   2 23 33 42
4   3 24 34 43
5   4 25 35 44
6   5 26 36 45
7   6 27 37 46
8   7 28 38 47
9   8 29 39 48
10  9 30 40 49

Have a look at mutate_at or mutate_if

library(dplyr)
df = tibble(a = LETTERS[1:10], b = 21:30,c=31:40)

#exclude column a
df %>% 
  mutate_at(vars(-("a")),lag)
#> # A tibble: 10 x 3
#>    a         b     c
#>    <chr> <int> <int>
#>  1 A        NA    NA
#>  2 B        21    31
#>  3 C        22    32
#>  4 D        23    33
#>  5 E        24    34
#>  6 F        25    35
#>  7 G        26    36
#>  8 H        27    37
#>  9 I        28    38
#> 10 J        29    39
#only column b
df %>% 
  mutate_at(c("b"),lag,4)
#> # A tibble: 10 x 3
#>    a         b     c
#>    <chr> <int> <int>
#>  1 A        NA    31
#>  2 B        NA    32
#>  3 C        NA    33
#>  4 D        NA    34
#>  5 E        21    35
#>  6 F        22    36
#>  7 G        23    37
#>  8 H        24    38
#>  9 I        25    39
#> 10 J        26    40
#only character column
df %>% 
  mutate_if(is.character,lag,3)
#> # A tibble: 10 x 3
#>    a         b     c
#>    <chr> <int> <int>
#>  1 <NA>     21    31
#>  2 <NA>     22    32
#>  3 <NA>     23    33
#>  4 A        24    34
#>  5 B        25    35
#>  6 C        26    36
#>  7 D        27    37
#>  8 E        28    38
#>  9 F        29    39
#> 10 G        30    40

Created on 2020-04-20 by the reprex package (v0.3.0)

4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Marcus Vance
Author

Marcus Vance

Marcus Vance is a cybersecurity auditor and technology writer dedicated to educating the public about online safety, data privacy regulations, enterprise security, and emerging cyber threats.