using mutate_at from dplyr

Viewed 9536

I have a data frame with 5 columns and I want to produce 4 additional columns giving my the difference between the last 4 columns and the first column. I tried the following, but that doesn't work:

library(tidyverse)
df <- as.tibble(data.frame(A = c(1,2), B = c(3,4), C = c(4,5), D = c(2,3), E = c(4,5)))
r_diff <- function(x,y){
  z = y - x
  return(z)
}
vars_to_process <- c("B","C","D","E")
df %>% mutate_at(.cols=vars_to_process, .funs =r_diff(.,df[,1])) %>% head()

Thanks Renger

3 Answers

Here's the simplest way to do it.

df %>% 
   mutate_at(.vars = vars(B:E),
             .funs = list(~ . - A))

The .vars argument lets you specify columns in the same way that you would specify columns in select(), provided you put that specification inside the function vars().

The .funs argument accepts an anonymous function defined on the fly inside a call to list(). And you can reference a column in the dataframe (in this case A) when defining this anonymous function (see this Stackoverflow question).

In addition, with the release of dplyr 1.0.0, you can now simply do the following:

df %>%
   mutate(across(B:E, ~ . - A))
Related