Передайте строку как имя переменной в dplyr :: filter
Я использую набор данных mtcars, чтобы проиллюстрировать мой вопрос.
Например, я хочу подмножить данные на 4-цилиндровые автомобили. Я могу сделать:
mtcars %>% filter(cyl == 4)
В моей работе мне нужно передать строковую переменную в качестве имени столбца. Например:
var <- 'cyl'
mtcars %>% filter(var == 4)
Я также сделал:
mtcars %>% filter(!!var == 4)
В обоих случаях я получил пустой фреймворк.
Ответы
Ответ 1
!!
или UQ
оценивает переменную, поэтому mtcars %>% filter(!!var == 4)
совпадает с mtcars %>% filter('cyl' == 4)
где условие всегда вычисляется как false; Вы можете доказать это, напечатав !!var
в функции фильтра:
mtcars %>% filter({ print(!!var); (!!var) == 4 })
# [1] "cyl"
# [1] mpg cyl disp hp drat wt qsec vs am gear carb
# <0 rows> (or 0-length row.names)
Чтобы оценить var
для столбца cyl
, вам нужно сначала преобразовать var
в символ cyl
, а затем вычислить символ cyl
в столбце:
Использование rlang
:
library(rlang)
var <- 'cyl'
mtcars %>% filter((!!sym(var)) == 4)
# mpg cyl disp hp drat wt qsec vs am gear carb
#1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
#3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
# ...
Или используйте as.symbol/as.name
из baseR:
mtcars %>% filter((!!as.symbol(var)) == 4)
mtcars %>% filter((!!as.name(var)) == 4)
Ответ 2
Я думаю, что ответ @snoram элегантен и зависит исключительно от dplyr
.
var <- c('cyl')
mtcars %>% filter(get(var) == 4)
Вы также можете использовать это со списком. В качестве простого примера вы можете получить счетчик каждого отфильтрованного столбца в качестве нового набора данных.
#adding car name
mtcars <- rownames_to_column(mtcars, "car_name")
#name your vectors
vector <- c("vs","am","carb")
df2 <- data.frame()
for (variable in vector) {
df1 <- mtcars %>% filter(get(variable) == 1) %>% summarise(variable = n_distinct(car_name)) %>% data.frame()
df2<- rbind(df2,df1)
}
Ответ 3
Вы можете использовать eval (parse (text = для вычисления строк как переменных:
mtcars %>% filter(eval(parse(text='cyl')) == 4)
![enter image description here]()