当前位置: 首页 > 知识库问答 >
问题:

管道内部有n_distinct的意外行为

郏瀚
2023-03-14

我试图在函数的管道中使用DPLYR中的N_DISTINCT函数,html" target="_blank">并发现它对我的语法选择非常敏感,这是我没有想到的。这里有一个玩具的例子。

# 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_distince放在管道中,并使用.引用筛选后的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_distince有什么奇怪的地方吗?

共有1个答案

薛淮晨
2023-03-14

N_DISTINCT接受多个参数,在这里您实际上同时传递了tibble和b列作为参数,因为默认情况下传递的是pipe的左侧。下面是一些获得预期输出的其他方法:

filter(X, !!sym(i) > 0) %>% 
  {n_distinct(.$b)}

filter(X, !!sym(i) > 0) %>% 
  with(n_distinct(b))

library(magrittr)

filter(X, !!sym(i) > 0) %$% 
  n_distinct(b)

另外,与你的问题没有直接关系的是,这类事情有一个方便的功能

map_dfr(str_subset(colnames(X), "a"), function(i) {

  value <- filter(X, !!sym(i) > 0) %>% {n_distinct(.$b)}

  tibble(y = i, n_uniq = value)

})
 类似资料:
  • 以下代码在调试模式下工作良好,因为_BitScanReverse64被定义为如果未设置位则返回0。引用MSDN:(返回值为)“如果已设置索引,则为非零;如果未找到设置位,则为0。” 如果在发布模式下编译此代码,它仍然可以工作,但是如果启用编译器优化,例如\o1或\o2,则索引不为零,将失败。 这是故意的行为吗?我正在使用Visual Studio Community 2015,版本14.0.254

  • 问题内容: 我正在尝试在作为Jenkins Pipeline一部分运行的docker容器内执行一些git查询。在docker容器外面,sshsgent工作正常,我可以访问我的SCM没问题。在容器内部,我收到主机密钥验证问题。 有人可以帮助我解决我所犯的错误吗? 首先whoami呼叫输出: docker容器输出中的第二个调用(和回显): 问题答案: 主机密钥验证失败 容器中的SSH连接无法验证主机(

  • 使用Python 3.3,我想循环d.items()并根据if条件返回匹配项。这是代码: 我希望打印“匹配”,但是我得到的是两个语句都相反打印,即, 如何让代码只打印正确的语句?感谢任何帮助。

  • 问题内容: 前一阵子,在使用Class.getMethod和自动装箱时,我遇到了类似的问题,因此在自己的查找算法中实现它很有意义。但是,真正让我感到困惑的是,以下两种方法也不起作用: String.class实现了Serializable接口,我确实希望它包含在lookup方法中。 我也必须在自己的查找算法中考虑这一点吗? 编辑 :我确实读过Javadoc, 所以让我强调一下问题的第二部分 :如果

  • 我是Python的新手,我对Python处理空对象的方式有点困惑。 考虑这段代码; 我得到了这段代码的以下输出。 我假设由{}初始化的对象是有效对象。为什么Python不那样对待它?为什么要得到diff If条件的diff输出? 在C++中,当我说 如果obj不是NULL,它将进入IF块(不管它是垃圾值还是其他) 但当我翻译成Python时也是一样的。 为什么?我读到Python将{}计算为fal

  • 我试图用async CompletableFuture创建一个简单的示例,但我看到了一些奇怪的行为。我的想法是启动两个异步未来,一个在设定时间后激活布尔标志,另一个轮询该标志,在线程1更改该标志后释放该值。这是我的代码: 而CF类: 当我让程序运行它的课程时,它会打印以下内容: 获取可完成的 开始睡觉 睡过了 进程已完成,退出代码为0 i、 e.未来永远不会在分配的10秒内完成。这是怎么回事?