懒惰求值、dplyr中的“filter”和NA值

4

我在使用惰性求值和dplyr时遇到了一些小问题。我试图过滤掉一些NA,但不知道为什么惰性求值版本不起作用。可能是我漏掉了什么,但我找不到原因。是这样吗,还是一个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"))

两段代码都可以运行而不会出现错误。


dplyr 的版本是什么? - Hong Ooi
不是很老,0.5.0版本。安装最新版本并尝试使用。 - Elijah
2个回答

3

dplyr已经从lazyeval切换到rlang(在这里有详细文档),弃用了*_函数,采用新的语法:

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

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")

谢谢!我知道我忘了什么! - Elijah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接