这是一个虚拟数据:
father<- c(1, 1, 1, 1, 1)
mother<- c(1, 1, 1, NA, NA)
children <- c(NA, NA, 2, 5, 2)
cousins <- c(NA, 5, 1, 1, 4)
dataset <- data.frame(father, mother, children, cousins)
dataset
father mother children cousins
1 1 NA NA
1 1 NA 5
1 1 2 1
1 NA 5 1
1 NA 2 4
Run Code Online (Sandbox Code Playgroud)
我想过滤这一行:
father mother children cousins
1 1 NA NA
Run Code Online (Sandbox Code Playgroud)
我可以这样做:
test <- dataset %>%
filter(father==1 & mother==1) %>%
filter (is.na(children)) %>%
filter (is.na(cousins))
test
Run Code Online (Sandbox Code Playgroud)
我的问题:我有很多专栏,如祖父,叔叔,叔叔,叔叔3,我想避免这样的事情:
filter (is.na(children)) %>%
filter (is.na(cousins)) %>%
filter (is.na(uncle1)) %>%
filter (is.na(uncle2)) %>%
filter (is.na(uncle3))
and so on...
Run Code Online (Sandbox Code Playgroud)
我如何使用dplyr来说明用na过滤所有列(父亲除外== 1&母亲== 1)
LMc*_*LMc 35
如果您使用 dplyr 版本 >= 1.0.4,您确实应该使用if_anyor if_all,它专门将谓词函数的结果组合成单个逻辑向量,使其在filter. 语法与 相同across,但添加了这些动词来帮助满足此需求:if_any/if_all。
library(dplyr)
dataset %>%
filter(if_all(-c(father, mother), ~ is.na(.)), if_all(c(father, mother), ~ !is.na(.)))
Run Code Online (Sandbox Code Playgroud)
这里我已经写出了变量名称,但是您可以使用任何整洁的选择帮助器来指定变量(例如,按名称或位置的列范围、正则表达式匹配、子字符串匹配、开头/结尾等)。
输出
father mother children cousins
1 1 1 NA NA
Run Code Online (Sandbox Code Playgroud)
mt1*_*022 24
使用预发布:
# > packageVersion('dplyr')
# [1] ‘0.5.0.9004’
dataset %>%
filter(!is.na(father), !is.na(father)) %>%
filter_at(vars(-father, -mother), all_vars(is.na(.)))
Run Code Online (Sandbox Code Playgroud)
似乎没有一个答案是适应性强的解决方案。我认为目的不是列出所有变量和值来过滤数据。
实现这一目标的一种简单方法是通过合并。如果您在 df_filter 中具备所有条件,那么您可以执行以下操作:
df_results = df_filter %>% left_join(df_all)
Run Code Online (Sandbox Code Playgroud)
一个dplyr解决方案:
test <- dataset %>%
filter(father==1 & mother==1 & rowSums(is.na(.[,3:4]))==2)
Run Code Online (Sandbox Code Playgroud)
其中 '2' 是应为的列数NA。
这给出:
> test
father mother children cousins
1 1 1 NA NA
Run Code Online (Sandbox Code Playgroud)
您也可以在基础 R 中应用此逻辑:
dataset[dataset$father==1 & dataset$mother==1 & rowSums(is.na(dataset[,3:4]))==2,]
Run Code Online (Sandbox Code Playgroud)