Alex
Alex

Reputation: 1304

Pass a variable name to a user written function that uses dyplr

I am trying to write a function that index variables names. In particular, in my function, I use mutate to encode a variable that I have without changing its name. Does anyone knows how I can index a variable on the left end side of mutate?

Here is an example

library(tydiverse)
# first create relevant dataset

iris <- iris%>% group_by(Species) %>% mutate(mean_Length=mean(Sepal.Length))

# second create my function
userfunction <- function(var){
  newdata <- iris  %>% 
    select(mean_Length,{var}) %>% distinct() %>% 
    mutate(get(var)= # this is what causes my function to fail. How can i refer to the `var` here?
factor(get(var),get(var))) %>% 
arrange(get(var)) # 
  return(newdata)
}
# this function produces the following error # Error: unexpected '}' in "}"

#note that if I change the reference to its original string the function works
userfunction2 <- function(var){
  newdata <- iris  %>% 
    select(mean_Length,{var}) %>% distinct() %>% 
    mutate(Species= # without reference it works, but I am unable to use the function for multiple variables. 
factor(get(var),get(var))) %>% 
arrange(get(var)) # 
  return(newdata)
}
encodedata<- userfunction2("Species")

Thanks a lot in advance for your help

Best

Upvotes: 0

Views: 31

Answers (2)

ktiu
ktiu

Reputation: 2626

Here is a working example that goes into a similar direction as Limey's answer:

iris <- datasets::iris %>%
  group_by(Species) %>%
  mutate(mean_Length=mean(Sepal.Length)) %>%
  ungroup()

userfunction <- function(var){
  iris  %>%
    transmute(mean_Length, "temp" = iris[[var]]) %>% 
    distinct() %>% 
    mutate("{var}" := factor(temp)) %>% 
    arrange(temp) %>%
    select(-temp)
}

userfunction("Petal.Length")

Upvotes: 1

Limey
Limey

Reputation: 12461

I don't think var is your problem. I think it's the =. If you you have a enquoted variable on the left hand side of the assignment (which is effectively what you do have with get()), you need :=, not =.

See here for more details.

I would have written your function slightly differently:

userfunction <- function(data, var){
  qVar <- enquo(var)
  
  newdata <- data  %>% 
    select(mean_Length,  !! qVar) %>% distinct() %>% 
    mutate(!! qVar := factor(!! qVar, !! qVar)) %>% 
    arrange(!! qVar)  
  return(newdata)
}

The inclusion of the data parameter means you can include it in a pipe:

encodedata <- iris %>% userfunction(Species)
encodedata
# A tibble: 3 x 2
# Groups:   Species [3]
  mean_Length Species   
        <dbl> <fct>     
1        5.01 setosa    
2        5.94 versicolor
3        6.59 virginica 

Upvotes: 0

Related Questions