【发布时间】:2020-05-01 06:57:08
【问题描述】:
我正在尝试在函数的管道内使用来自dplyr 的n_distinct 函数,并且发现它以一种我没有预料到的方式对我选择的语法很敏感。这是一个玩具示例。
# preliminaries
library(tidyverse)
set.seed(123)
X <- data.frame(a1 = rnorm(10), a2 = rnorm(10), b = rep(LETTERS[1:5], times = 2), stringsAsFactors = FALSE)
print(X)
a1 a2 b
1 -0.56047565 1.2240818 A
2 -0.23017749 0.3598138 B
3 1.55870831 0.4007715 C
4 0.07050839 0.1106827 D
5 0.12928774 -0.5558411 E
6 1.71506499 1.7869131 A
7 0.46091621 0.4978505 B
8 -1.26506123 -1.9666172 C
9 -0.68685285 0.7013559 D
10 -0.44566197 -0.4727914 E
好的,现在假设我想在该数据框中选定列的名称上迭代一个函数(幽默)。在这里,我将使用所选列中的值来过滤初始数据集,计算剩余的唯一 ID 的数量,并将结果作为单行 tibble 返回,然后我将其绑定到新的 tibble。当我在函数中创建一个新的 tibble,然后将 n_distinct 应用到该 tibble 中的选定列作为其自己的步骤时,我会从 n_distinct、5 和 4 中得到预期的结果。
bind_rows(map(str_subset(colnames(X), "a"), function(i) {
subdf <- filter(X, !!sym(i) > 0)
value <- n_distinct(subdf$b)
tibble(y = i, n_uniq = value)
}))
# A tibble: 2 x 2
y n_uniq
<chr> <int>
1 a1 5
2 a2 4
如果我将 n_distinct 放在管道中并使用 . 来引用过滤后的 tibble,那么代码会执行,但我会得到不同且不正确的结果。
bind_rows(map(str_subset(colnames(X), "a"), function(i) {
value <- filter(X, !!sym(i) > 0) %>% n_distinct(.$b)
tibble(y = i, n_uniq = value)
}))
# A tibble: 2 x 2
y n_uniq
<chr> <int>
1 a1 5
2 a2 7
那是怎么回事?我是否误解了在管道内使用.? n_distinct 有什么时髦之处吗?
【问题讨论】: