dplyr条件选择中波浪号(~)的作用及无左值时的工作原理
问题:dplyr的select_if中,无左值的波浪号(~)如何工作?
原始数据集:
#> data_name col_a col_b #> <chr> <int> <int> #> 1 data_a 30 NA #> 2 data_b 20 75 #> 3 sum 50 NA
为筛选不含NA值的列,使用了以下dplyr代码:
data_without_na <- raw_data %>% select_if(~ !any(is.na(.))) data_without_na
得到预期输出:
#> data_name col_a #> <chr> <int> #> 1 data_a 30 #> 2 data_b 20 #> 3 sum 50
现有理解:
- R中波浪号(~)通常用于分隔等式左右侧
!表示取反any(is.na(.))用于判断每列是否存在NA值,返回布尔值
困惑点:为什么这个条件开头需要加波浪号(~),尤其是没有左侧变量的情况下,它是如何工作的?
解答
在tidyverse系列包(比如dplyr)的函数里,这里的~是简化匿名函数(lambda函数)的语法糖,和你熟悉的公式(比如线性模型lm(y~x))用法完全不同。
具体到select_if()的执行逻辑:
select_if()会遍历数据框的每一列,把当前列作为输入参数传入判断逻辑~的作用是告诉dplyr:后面跟着的表达式是一个要作用于每一列的函数- 表达式里的
.代表当前正在被处理的那列数据
你写的~ !any(is.na(.)),完全等价于完整的匿名函数写法:
function(x) { !any(is.na(x)) }
之所以不用写左侧变量,是因为select_if()已经默认将每一列作为输入参数传递给这个匿名函数了,~帮你省略了function(x)的声明,让代码更简洁紧凑。
总结一下:这里的~就是tidyverse为这类逐元素处理的场景设计的简化语法,用来快速定义一个临时的小函数。
内容的提问来源于stack exchange,提问作者seemoreseaglass
相关产品推荐
相关产品推荐

