惰性评估、dplyr "filter" 和 NA
Lazy eval, dplyr "filter" and NAs
我在使用惰性求值和 dplyr 时遇到了一些愚蠢的问题。
我正在尝试过滤一些 NA
s 并且不知道为什么 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"))
两个代码 运行 都没有抛出错误。
您需要将 "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")
dplyr 已将其 NSE 系统从 lazyeval 切换到 rlang (documented 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
我在使用惰性求值和 dplyr 时遇到了一些愚蠢的问题。
我正在尝试过滤一些 NA
s 并且不知道为什么 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"))
两个代码 运行 都没有抛出错误。
您需要将 "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")
dplyr 已将其 NSE 系统从 lazyeval 切换到 rlang (documented 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