在stopifnot()中使用dplyr管道传值为何未得到预期TRUE结果?
为什么管道方式调用
stopifnot()会触发报错? 你遇到的问题核心是管道运算符%>%的参数传递逻辑和stopifnot()的调用规则不匹配。
先拆解错误的本质:
当你写df_uniques %>% stopifnot(. == nrow(df))时,%>%会默认把左侧的df_uniques作为第一个参数传给stopifnot(),这行代码实际等价于:
stopifnot(df_uniques, . == nrow(df))
而stopifnot()要求所有传入的表达式都必须是全为TRUE的逻辑向量。这里第一个参数df_uniques是数值10,不是逻辑值,直接违反了要求,所以触发报错——和后面的. == nrow(df)是否为TRUE无关。
而直接写stopifnot(df_uniques == nrow(df))时,传入的是一个完整的逻辑表达式,计算结果是TRUE,符合要求,所以正常运行。
解决办法
要让管道配合stopifnot()正常工作,需要明确告诉管道:把左侧的值传给表达式里的.,而不是作为stopifnot()的第一个参数。可以用两种方式实现:
- 用大括号包裹
stopifnot()调用,改变管道的参数传递行为:
# 正确的管道写法 df_uniques %>% {stopifnot(. == nrow(df))} # 正常运行 df_uniques %>% {stopifnot(. == df_rows)} # 正常运行
大括号会创建一个匿名函数,管道左侧的值会被赋值给.,此时stopifnot()只接收我们指定的逻辑表达式。
- 用
magrittr包的%$%运算符(dplyr已包含该运算符),它会直接将左侧对象暴露给右侧表达式:
df_uniques %$% stopifnot(. == nrow(df)) # 正常运行
验证代码
完整可运行的示例:
library(dplyr) # 数据准备 df <- data.frame(x = 1:10) df_rows <- df_uniques <- df %>% nrow() # 错误写法(触发报错) # df_uniques %>% stopifnot(. == nrow(df)) # 正确写法 df_uniques %>% {stopifnot(. == nrow(df))} df_uniques %>% {stopifnot(. == df_rows)} stopifnot(df_uniques == nrow(df)) stopifnot(df_uniques == df_rows)
内容的提问来源于stack exchange,提问作者socialscientist
相关产品推荐
相关产品推荐

