dplyr过滤器,具有多列条件

Wil*_*car 13 r dplyr

这是一个虚拟数据:

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

如果您使用 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)


Jfl*_*fly 6

似乎没有一个答案是适应性强的解决方案。我认为目的不是列出所有变量和值来过滤数据。

实现这一目标的一种简单方法是通过合并。如果您在 df_filter 中具备所有条件,那么您可以执行以下操作:

df_results = df_filter %>% left_join(df_all)
Run Code Online (Sandbox Code Playgroud)


Jaa*_*aap 5

一个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)