Search code examples
rfunctiondplyrattr

Access variable attributes inside dplyr user defined function


I'm trying to create a function to compute weighted averages from survey data, where the variable name is taken from a variable attribute. I have imported a dataset where each variable already has a label Here's a reproducible example:

random_df<- data.frame(replicate(5,sample(0:1,10,rep=TRUE)))
attr(random_df$X1, 'label') <-"Age"
attr(random_df$X2, 'label') <-"Gender"
attr(random_df$X3, 'label') <-"Occupation"
attr(random_df$X4, 'label') <-"Nationality"
attr(random_df$X5, 'label') <-"Education"

I would like to create a function that computes weighted averages and names the variables from the label. I tried the following


my_function<- function(var, ...){
  var<-enquo(var)
  group_var <- enquos(...)
  df <-random_df

label<-attr(df$!!var,'label')

  df %>%
    filter(!is.na(!!var))%>%
    group_by(!!!group_var) %>%
    count(!!var) %>%
    mutate(freq=n/sum(n)) %>%
    mutate(!!label:=percent(freq)) 

}

This however gives me an error Error: unexpected '!' in:" label<-attr(df$!". Would anyone know how to fix the code?


Solution

  • Try this:

    my_function<- function(var, ...){
      var <- enexpr(var) # use expression, not quosure
      group_var <- enquos(...)
      df <-random_df
    
      label<-attr(df[[as.character(var)]],'label') # use as.character, not unquoting
    
      df %>%
        filter(!is.na(!!var))%>%
        group_by(!!!group_var) %>%
        count(!!var) %>%
        mutate(freq=n/sum(n)) %>%
        mutate(!!label:=percent(freq)) 
    }
    

    We use df[[as.character(var)]] instead of df$!!var because unquoting with !! fails in this case. Also note that you probably want expressions, not quosures here. For as.character we specifically need an expression.

    (Thanks for updating with the reproducible example!)