2015-02-04 2 views
5

Как я могу передать имя столбца в функции аналогична вопросом here, но с использованием dplyr цепочки и filter() вместе с %in%.R, передать имя столбца в качестве аргумента функции с использованием dplyr :: фильтра() и% в%

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

Если хотите получить строки, в которых столбец А 1 или 2 я могу сделать:

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

я получаю:

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

Теперь, как я могу сделать это в функции , где можно указать колонку, это не работает:

fun1 <- function(x, column, n){ 
    res <- 
    x %>% filter(column %in% n) 
    return(res) 
} 
fun1(df, A, c(1,2)) 

ответ

8

Вы может попробовать

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

Или

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

fun2(df, A, 1:2) 
+0

Это что-то хорошее см. сейчас. Когда я задал подобный вопрос некоторое время назад, @aosmith дал хороший ответ. Здесь я вижу обновленную версию. Сегодня я делаю заметки. :) +1 – jazzurro

+0

@jazzurro Спасибо за комментарий. – akrun

+0

@akrun вы могли бы поместить объяснение для своего варианта 2 - будет ли 'match.call()' содержать все аргументы, которые помещаются внутри функции? И как это интерпретируется 'filter()' в 'eval()'? – user3375672

4

Если вы хотите сохранить свою функцию, попробуйте:

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

fun1(df, "A", "c(1,2)") 
2

Попробуйте изменить функцию

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 
Смежные вопросы