如何在tidyverse管道中测试数据框列数是否符合预期?
解决tidyverse管道中测试列数的问题
你遇到的问题是因为if是R的控制流语句而非函数,管道操作符%>%没办法自动把前一步的输出(也就是.)传递给它,导致ncol(.)无法正确解析。下面有几种符合tidyverse风格的简便解决方案:
方案1:用大括号包裹代码块
在管道中,当你需要执行的不是一个接受数据框作为第一个参数的函数时,用{}把代码逻辑包起来,这样.就能正确指代管道前一步的输出:
library(tidyverse) mtcars %>% select_if(negate(is.numeric)) %>% {if(ncol(.) > 0) stop("there should be no non-numeric column!")}
这个方法直接利用R的代码块特性,让.在if条件中被正确识别。
方案2:用dplyr::verify(更贴合tidyverse风格)
dplyr提供了verify函数,专门用于在管道中验证数据框的条件,语法更简洁直观:
mtcars %>% select_if(negate(is.numeric)) %>% verify(ncol(.) == 0, msg = "there should be no non-numeric column!")
如果条件不满足,verify会自动抛出你指定的错误信息,完全适配管道工作流。
原代码出错原因
原代码中,%>%尝试把前一步的输出传给if,但if不是函数,它不会接收这个参数,所以.在if(ncol(.) > 0)中并没有被绑定到任何对象,导致ncol(.)返回NULL,进而触发"argument is of length zero"的错误。
内容的提问来源于stack exchange,提问作者Sebastian Sauer
相关产品推荐
相关产品推荐

