Search code examples
rdplyrlazy-evaluationnse

Function with dplyr and multiple statements


I am having trouble using several dplyr functions in one function, despite using the function variants.

Example

library(dplyr)

# Data:
mydf <- data.frame( 
  var1     = factor(rep(1:24, each = 100)),
  var2    = runif(2400, min = -10, max = 125),
  var3     = runif(2400, min = 0, max = 2500),
  var4     = runif(2400, min = - 10, max = 25)  
)

# The function I want to build: 


fx.average <- function(df, varlist) {
  # select some varibles from a data frame
  df <- df %>% dplyr::select_(.dots = varlist)

   # Group by a variable and then just calculate the mean
  df <-df %>% dplyr::group_by_(var1) %>% # added df here
    dplyr::summarise_each_(funs_(mean(., na.rm = TRUE)))
}

So, now I am going to test the function in the following:

# Test function, Setup var-list
varlist0 <- c("var1", "var2", "var3")    

fx.average(mydf, varlist0)
# Error in dplyr::group_by_(var1) : object 'var1' not found
#  object 'var1' not found 


# Manual example
mydf %>% dplyr::select(var1, var2, var3) %>% 
  group_by(var1) %>% 
  summarise_each(funs(mean(., na.rm = TRUE)))

Not sure what goes wrong? From other questions it seems it should be solved by adding an underscore to the functions - since they are build for use inside functions?


Solution

  • In the OP's code, there are some typos (not specifying the data in the group_by step along with using NSE without quoted string and using funs_ with summarise_each_ where summarise_each and funs works)

    fx.average <- function(df, varlist) {
      df %>% 
          dplyr::select_(.dots = varlist) %>%
          dplyr::group_by_(.dots = "var1") %>% 
          dplyr::summarise_each(funs(mean(., na.rm = TRUE)))
      }
    
    fx.average(mydf, varlist0)
    # A tibble: 24 × 3
    #     var1     var2     var3
    #   <fctr>    <dbl>    <dbl>
    #1       1 55.13601 1141.021
    #2       2 59.16508 1155.226
    #3       3 59.64524 1245.043
    #4       4 60.12310 1284.808
    #5       5 57.65874 1221.771
    #6       6 58.86611 1266.026
    #7       7 66.13987 1303.927
    #8       8 54.21595 1303.638
    #9       9 63.84230 1280.380
    #10     10 49.15238 1236.456
    # ... with 14 more rows