懒惰的eval,dplyr“过滤器”和NA

时间:2017-07-08 16:21:33

标签: r dplyr na lazyeval

我在使用延迟评估和dplyr时遇到了一些愚蠢的问题。 我正在尝试过滤一些NA,并且不知道为什么lazyeval版本不起作用。可能我错过了一些东西,但我找不到它。是这样,还是一个bug?

这是一个可重复的最小例子:

library(dplyr)
library(lazyeval)

data(iris)
iris$t <- c(1:140, rep(NA, 10))

#This Works
temp <- filter(iris, !is.na(t))

#This doesn't
temp <- filter_(iris, interp(~(!is.na(x)), x="t"))

两个代码都运行时没有抛出错误。

2 个答案:

答案 0 :(得分:3)

dplyr已将其NSE系统从lazyeval切换到rlang(记录为here),弃用*_函数以支持新语法:

library(dplyr)

data(iris)
iris <- iris %>% mutate(t = c(1, rep(NA, 149)))

# normal NSE
iris %>% filter(!is.na(t))
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species t
#> 1          5.1         3.5          1.4         0.2  setosa 1

# string-based SE; use `rlang::sym` to convert to quosure and !! to unquote
x <- "t"
iris %>% filter(!is.na(!!rlang::sym(x)))
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species t
#> 1          5.1         3.5          1.4         0.2  setosa 1

# program your own NSE with `quo` and friends
x <- quo(t)
iris %>% filter(!is.na(!!x))
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species t
#> 1          5.1         3.5          1.4         0.2  setosa 1

# both versions work across the tidyverse
iris %>% tidyr::drop_na(!!x)
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species t
#> 1          5.1         3.5          1.4         0.2  setosa 1

# though tidyr::drop_na is happy with strings anyway
iris %>% tidyr::drop_na("t")
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species t
#> 1          5.1         3.5          1.4         0.2  setosa 1

答案 1 :(得分:2)

您需要传递"t"作为名称。

interp(~(!is.na(x)), x = as.name("t"))
# ~!is.na(t)

正如您的代码所代表的那样,您将"t"插入is.na()以制作is.na("t"),每次都为FALSE。并且否定每次都给出TRUE,因此所有行都是。

interp(~(!is.na(x)), x = "t")
# ~!is.na("t")