Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `dplyr::mutate()` to create several new variables from names specified in a vector

I want to create several new empty variables in a dataframe where I specify the variable names in a vector. This works if I only specify one variable name, but breaks with several. I tried some previous solutions, but they didn't seem to work in this case, e.g.:

  • dplyr without hard-coding the variable names
  • Pass a vector with names to mutate to create multiple new columns
  • dplyr - mutate: use dynamic variable names

library(dplyr)

add_columns <- function(df, columns){
    columns <- quo(columns)
    mutate(df, !!columns := NA_character_)
}

columns <- c("x", "y")
iris %>% 
    add_columns(columns)

 Error: The LHS of `:=` must be a string or a symbol

The desired output would be:

# A tibble: 150 x 7
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species x     y    
          <dbl>       <dbl>        <dbl>       <dbl> <fct>   <chr> <chr>
 1         5.10        3.50         1.40       0.200 setosa  NA    NA   
 2         4.90        3.00         1.40       0.200 setosa  NA    NA   
 3         4.70        3.20         1.30       0.200 setosa  NA    NA   
 4         4.60        3.10         1.50       0.200 setosa  NA    NA   
 5         5.00        3.60         1.40       0.200 setosa  NA    NA   
 6         5.40        3.90         1.70       0.400 setosa  NA    NA   
 7         4.60        3.40         1.40       0.300 setosa  NA    NA   
 8         5.00        3.40         1.50       0.200 setosa  NA    NA   
 9         4.40        2.90         1.40       0.200 setosa  NA    NA   
10         4.90        3.10         1.50       0.100 setosa  NA    NA   
# ... with 140 more rows

I wonder how can I make this work?

like image 803
Tamas Nagy Avatar asked Mar 06 '23 18:03

Tamas Nagy


1 Answers

You don't need any quosures here because you are not dealing with quoted expressions. Just create vectors with appropriate names and splice them in. Here I use the fact that vectors of length 1 are recycled, but you could also create vectors of full length:

add_columns <- function(df, columns){
  new <- rep(NA_character_, length(columns))
  names(new) <- columns
  mutate(df, !!!new)
}
like image 156
Lionel Henry Avatar answered Mar 09 '23 17:03

Lionel Henry