Joost Keuskamp
Joost Keuskamp

Reputation: 125

mixing constant and variable column names in dplyr::mutate/transmute

I am trying to change the class of a dataframe column using dplyr. The name of the target column is contained in a variable

my_df<-data.frame(colour=c("red","blue","green"),
                  val1=as.character(c(1,12,13)),
                  val2=c(21,22,23))

target_var="val1"

After some fiddling I managed to reach my goal using standard R subsetting:

my_df %>% transmute(colour = colour,
                 !!myval := as.numeric(.[,myval]))

But I suspect that there are less complex ways of referring to the target column, which is more consistent with other 'dplyr' expressions. I have tried solving this question with the information from the "Programming with dplyr" vignette, but no luck. Could anyone point me in the right direction?

Upvotes: 1

Views: 1096

Answers (3)

Joost Keuskamp
Joost Keuskamp

Reputation: 125

I've found how to do this with a minimum of conversions:

my_df<-data.frame(colour=c("red","blue","green"),
              val1=as.character(c(1,12,13)),
              val2=c(21,22,23))

target_var="val1"

my_df %>% transmute(colour = colour,
                 !!my_val := as.numeric(!!as.symbol(target_var)))

Upvotes: 1

akrun
akrun

Reputation: 887128

We could use the sym to convert to symbol and then with !!

my_df %>%
    transmute(colour = colour, 
        !!target_var := as.numeric(as.character(!!rlang::sym(target_var))))
#    colour val1
#1    red    1
#2   blue   12
#3  green   13

NOTE: There the 'val1' is factor because by default stringsAsFactors = TRUE. So, we need to convert it to character and then to numeric

data

my_df<-data.frame(colour=c("red","blue","green"),
              val1=as.character(c(1,12,13)),
              val2=c(21,22,23))

target_var <- "val1"

Upvotes: 3

David
David

Reputation: 10162

You are looking for the mutate_at function. Your code would look like this then:

library(tidyverse) # to load dplyr and tibble

# I took the liberty to add val3 to show how you can do it with multiple variables
my_df <- data_frame(colour = c("red", "blue", "green"),
                    val1 = as.character(c(1, 12, 13)),
                    val2 = c(21, 22, 23),
                    val3 = as.character(c(1, 12, 13)))

# same here...
target_var <- c("val1", "val3")


my_df %>% 
  mutate_at(.funs = as.numeric, .vars = target_var)
#> # A tibble: 3 x 4
#>   colour  val1  val2  val3
#>    <chr> <dbl> <dbl> <dbl>
#> 1    red     1    21     1
#> 2   blue    12    22    12
#> 3  green    13    23    13

The only drawback to this method is that you end up with the full dataset (mutate) and not with the selected variables (as you would with transmutate). You could use transmutate_at, but that applies the supplied function to all selected variables.

Upvotes: 4

Related Questions