Reputation: 2876
I have a data-frame where I want to pass a column name to R in and then filter based on that column. I have tried reading a few tutorials on this and it seems to be related to non standard evaluation in R.
I cant seem to wrap my head around the examples in the blog posts I have read. Just for simplicity, I have taken the iris dataset and I want to pass a column to a function which will then filter that dataset where the column value is greater than one.
mydf <- iris
filter_measurements <- function(mydf, measurement){
mydf <- filter(measurement >= 1)
mydf
}
mydf %>%
filter_measurements(measurement = Petal.Width)
Do I have to add something to my function so that R knows I want a column and not use it as 'Petal.Width' for example.
I have seen Passing a variable name to a function in R which i was unable to adapt to my example
Thank you all for your time
Upvotes: 0
Views: 389
Reputation: 46
You have to pass the column name either as character or integer index of the column. Also, the line
mydf <- filter(measurement >= 1)
within your function never states what is being filtered and will expect the "measurement" to be a stand-alone object, not a part of a data frame. Try this:
filter_measurements <- function(mydf, measurement)
{
mydf <- filter(mydf, mydf[,measurement] >= 1)
mydf
}
iris %>% filter_measurements("Petal.Width")
A more convoluted invocation of the function would also work:
iris %>% filter_measurements(which(names(.)=="Petal.Width"))
Upvotes: 1
Reputation: 7724
A great resource for this is Programming with dplyr.
mydf <- iris
filter_measurements <- function(mydf, measurement){
measurement <- enquo(measurement)
mydf <- filter(mydf, (!!measurement) >= 1)
mydf
}
mydf %>%
filter_measurements(measurement = Petal.Width)
You have to tell the function that measurement is giving as a bare variable name. For this first use enquo
to evaluate what is given in the measurement argument and store it as a quosure. Then with !!
in front of measurement the filter
function knows that it doesn't have to quote this argument, as it is already a quosure.
Alternative
You can also pass the column you want to filter on as a string and use filter_
:
filter_measurements <- function(mydf, measurement){
mydf <- filter_(mydf, paste0(measurement, " >= 1"))
mydf
}
mydf %>%
filter_measurements(measurement = "Petal.Width")
Upvotes: 2