2
votes

I am trying to create a function that will accept a data.frame and an integer representing the value for a specific year (such as 2015). The function will then use Dplyr and return a filtered data set.

The following is some test data, libraries and a non-parameterised dplyr call:

library(dplyr)
library(lazyeval)
library(lubridate

vct_dates <- c("2015-04-30", "2015-04-30", "2012-04-30", "2010-04-30")
vct_numbers <- c(21, 45, 103, 214)
df_test <- data.frame(date = vct_dates, value = vct_numbers)

df_test %>% filter(year(date) == 2015)

Now, the following is my attempt to encapsulate this functionality into a function:

fn_filter_year <- function(df_data, intYear) {
filter_condition <- interp(quote(year(x) == y), x=as.name("date"), y = intYear)
df_data %>% filter_(filter_condition)
return(df_data)

}

I am getting an error that "could not find the function 'year' " ??

Any suggestions would be really appreciated.

2

2 Answers

0
votes

This is because the call you are creating is not capturing the envioronment in which you are creating it. The easiest fix is just to use interp() on a formula rather than a call because a formula retains its environment. You can use

fn_filter_year <- function(df_data, intYear) {
    filter_condition <- interp(~year(x) == y, x=as.name("date"), y = intYear)
    df_data %>% filter_(filter_condition)
}

fn_filter_year(df_test, 2015)
#         date value
# 1 2015-04-30    21
# 2 2015-04-30    45
3
votes

Use filter instead of filter_ like this:

filter_year <- function(data, intYear) filter(data, year(date) == intYear)

filter_year(df_test, 2015) # test

giving:

        date value
1 2015-04-30    21
2 2015-04-30    45

If the idea was to separate out the condition then your code will work if you add year = year to the interp:

fn_filter_year <- function(df_data, intYear) {
    condition <- interp(quote(year(x) == y), x = as.name("date"), y = intYear, year = year)
    df_data %>% filter_(condition)
}

fn_filter_year(df_test, 2015) # test

giving the same output as above.