Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R, pass column name as argument to function using dplyr::filter() and %in%

Tags:

r

filter

dplyr

How can I pass a column name in a function similar to the question here but using dplyr chaining and filter() together with %in%.

require(dplyr)
set.seed(8)
df <- data.frame(
  A=sample(c(1:3), 10, replace=T), 
  B=sample(c(1:3), 10, replace=T))

If want to get rows where column A is 1 or 2 I can do:

df %>% filter(A %in% c(1,2))

I get:

  A B
1 2 3
2 1 2
3 1 3
4 2 1
5 1 1
6 1 3

Now, how can I put this in a function, where one can specify the column, this does not work:

fun1 <- function(x, column, n){
  res <- 
    x %>% filter(column %in% n)
  return(res)
}
fun1(df, A, c(1,2))
like image 410
user3375672 Avatar asked Feb 04 '15 14:02

user3375672


3 Answers

You could try

fun1 <- function(x, column, n){
 x %>% 
  filter_(lazyeval::interp(quote(x %in% y), x=as.name(column), y=n))
 }
fun1(df, 'A', 1:2)

Or

fun2 <- function(x, column, n){
   args <- as.list(match.call())
   x %>%
     filter(eval(args$column, x) %in% n)
 }

 fun2(df, A, 1:2)
like image 52
akrun Avatar answered Nov 02 '22 22:11

akrun


If you want to keep your function, try:

fun1 <- function(x, column, n){
  res <- x %>% filter_(paste(column,"%in%",n))
  return(res)
}

fun1(df, "A", "c(1,2)")
like image 4
NicE Avatar answered Nov 02 '22 22:11

NicE


Try changing your function to

fun1 <- function(x, column, n){
    require(lazyeval)
    filter_(x,
        interp(quote(col %in% n),
            col = lazy(column), n = n))
}

all(fun1(df, A, c(1, 2)) == filter(df, A %in% c(1,2)))
# TRUE
like image 2
konvas Avatar answered Nov 02 '22 23:11

konvas