dplyr 中的函数评估总结
Function evaluation in dplyr summarize
我想我遗漏了一些关于 R 如何评估事物的基本知识。考虑以下因素:
library("tidyverse")
dt0 <- tibble(x=1:10, y=11:20)
filter(dt0, 1==x) # Returns the first row
purrr::contains(list(1), 1) # TRUE
filter(dt0, purrr::contains(list(1), x)) # Returns NO rows
我尝试将 contains
包装在一个自定义函数中(没有变化),并添加了一个打印语句来尝试调试它,但据我所知,即使 [=12 的值=] 为 1(class 仍然是数字),contains(list(1), x)
returns TRUE
在过滤器外部,但 FALSE
在过滤器内部。
- 为什么?
可能相关,我真的不明白如何将列传递给 unique
之类的函数,但也传递给其他函数(比如我的自定义函数)。 (我知道你可以做,但不知道它是如何实现的。)我的自定义函数表现得好像它被调用了多次,对每个 x 值调用一次。 unique
,但是,必须有 所有 值,是吗?
unique
和单参数函数如何在列上工作?
问题似乎归结为比较的 类。在 purrr::contains()
的源代码中,正在调用 indentical()
来比较 dt0$x
和 list[[i]]
。 dt0$x
的内容是整数,而 1
不是。所以要解决这个问题,我们可以使用 1L
.
> is.integer(1:10)
[1] TRUE
> is.integer(1)
[1] FALSE
> identical((1:10)[1], 1)
[1] FALSE
> identical((1:10)[1], 1L)
[1] TRUE
然而,对 filter(dt0, purrr::contains(list(1L), x))
的调用仍将 return 零行,因为第二个参数未在 purrr::contains()
中迭代。所以它正在检查整个列 x
是否包含在 list(1)
中(当然是 FALSE
)。如果您想以这种方式使用 purrr::contains
,则必须手动遍历第二个参数。
我认为语法不是那么优雅,但如果您想留在 purrr
中,您可以使用:
> filter(dt0, purrr::map_lgl(x,~purrr::contains(list(1L), .x)))
# A tibble: 1 × 2
x y
<int> <int>
1 1 11
我想我遗漏了一些关于 R 如何评估事物的基本知识。考虑以下因素:
library("tidyverse")
dt0 <- tibble(x=1:10, y=11:20)
filter(dt0, 1==x) # Returns the first row
purrr::contains(list(1), 1) # TRUE
filter(dt0, purrr::contains(list(1), x)) # Returns NO rows
我尝试将 contains
包装在一个自定义函数中(没有变化),并添加了一个打印语句来尝试调试它,但据我所知,即使 [=12 的值=] 为 1(class 仍然是数字),contains(list(1), x)
returns TRUE
在过滤器外部,但 FALSE
在过滤器内部。
- 为什么?
可能相关,我真的不明白如何将列传递给 unique
之类的函数,但也传递给其他函数(比如我的自定义函数)。 (我知道你可以做,但不知道它是如何实现的。)我的自定义函数表现得好像它被调用了多次,对每个 x 值调用一次。 unique
,但是,必须有 所有 值,是吗?
unique
和单参数函数如何在列上工作?
问题似乎归结为比较的 类。在 purrr::contains()
的源代码中,正在调用 indentical()
来比较 dt0$x
和 list[[i]]
。 dt0$x
的内容是整数,而 1
不是。所以要解决这个问题,我们可以使用 1L
.
> is.integer(1:10)
[1] TRUE
> is.integer(1)
[1] FALSE
> identical((1:10)[1], 1)
[1] FALSE
> identical((1:10)[1], 1L)
[1] TRUE
然而,对 filter(dt0, purrr::contains(list(1L), x))
的调用仍将 return 零行,因为第二个参数未在 purrr::contains()
中迭代。所以它正在检查整个列 x
是否包含在 list(1)
中(当然是 FALSE
)。如果您想以这种方式使用 purrr::contains
,则必须手动遍历第二个参数。
我认为语法不是那么优雅,但如果您想留在 purrr
中,您可以使用:
> filter(dt0, purrr::map_lgl(x,~purrr::contains(list(1L), .x)))
# A tibble: 1 × 2
x y
<int> <int>
1 1 11