Ответ 1
Вы можете использовать функцию get
для извлечения значения переменной из среды.
df %>% filter(b == get("b")) # Note the "" around b
У меня есть переменная с тем же именем, что и столбец в dataframe:
df <- data.frame(a=c(1,2,3), b=c(4,5,6))
b <- 5
Я хочу получить строки, где df$b == b
, но dplyr интерпретирует это как df$b == df$b
:
df %>% filter(b == b) # interpreted as df$b == df$b
# a b
# 1 1 4
# 2 2 5
# 3 3 6
Если я изменяю имя переменной, она работает:
B <- 5
df %>% filter(b == B) # interpreted as df$b == B
# a b
# 1 2 5
Мне интересно, есть ли лучший способ сказать filter
, что b
относится к внешней переменной.
Вы можете использовать функцию get
для извлечения значения переменной из среды.
df %>% filter(b == get("b")) # Note the "" around b
В качестве общего решения вы можете использовать версию SE (стандартная оценка) filter
, которая равна filter_
. В этом случае все становится немного запутанным, потому что вы смешиваете переменную и "внешнюю" константу в одном выражении. Вот как вы это делаете с помощью функции interp
:
library(lazyeval)
df %>% filter_(interp(~ b == x, x = b))
Если вы хотите использовать больше значений в b
, вы можете написать:
df %>% filter_(interp(~ b == x, .values = list(x = b)))
Недавно я нашел, что это изящное решение этой проблемы, хотя я только начинаю обнимать ее, как это работает.
df %>% filter(b == !!b)
который является синтаксическим сахаром для
df %>% filter(b == UQ(b))
Мой высокий уровень этого заключается в том, что операция UQ
(без кавычек) приводит к тому, что ее содержимое оценивается до операции фильтра, поэтому оно не оценивается внутри data.frame.
Это описано в article в разделе 'quasi-quotation'. Я хотел бы отметить, что эта статья также включает несколько решений аналогичных проблем, связанных с NSE.
Одно предостережение выше - я склонен положить !!
в конце моих выражений, как указано выше. Если вы поместите это в начале:
df %>% filter(!!b == b)
то он будет оцениваться как df %>% filter(!!(b == b))
что эквивалентно записи df %>% filter(5 == 5)
:
> quo(filter(df, !!b == b))
<quosure: global>
~filter(df, TRUE)
В приведенной выше опции UQ()
этой проблемы нет.