使用group_by过滤特定情况,同时保持NA

b22*_*222 2 r dplyr

我想过滤我的数据集,以便在特定列中保留具有观察结果的案例.为了显示:

help <- data.frame(deid = c(5, 5, 5, 5, 5, 12, 12, 12, 12, 17, 17, 17),
               score.a = c(NA, 1, 1, 1, NA, NA, NA, NA, NA, NA, 1, NA))
Run Code Online (Sandbox Code Playgroud)

创建

   deid score.a
1     5      NA
2     5       1
3     5       1
4     5       1
5     5      NA
6    12      NA
7    12      NA
8    12      NA
9    12      NA
10   17      NA
11   17       1
12   17      NA
Run Code Online (Sandbox Code Playgroud)

我想告诉dplyr保留有任何观察结果的案例score.a,包括NA值.因此,我希望它返回:

  deid score.a
1     5      NA
2     5       1
3     5       1
4     5       1
5     5      NA
6    17      NA
7    17       1
8    17      NA
Run Code Online (Sandbox Code Playgroud)

我运行了代码,help %>% group_by(deid) %>% filter(score.a > 0)但它也拉出了NA.谢谢你的帮助.

编辑:这里问了一个类似的问题如何用dplyr :: filter()删除观察组 但是,在答案中他们使用'all'条件,这需要使用'any'条件.

akr*_*run 5

尝试

library(dplyr)
help %>%
      group_by(deid) %>%
      filter(any(score.a >0 & !is.na(score.a)))
#    deid score.a
#1    5      NA
#2    5       1
#3    5       1
#4    5       1
#5    5      NA
#6   17      NA
#7   17       1
#8   17      NA
Run Code Online (Sandbox Code Playgroud)

或类似的方法 data.table

library(data.table)
setDT(help)[, if(any(score.a>0 & !is.na(score.a))) .SD , deid]
#    deid score.a
#1:    5      NA
#2:    5       1
#3:    5       1
#4:    5       1
#5:    5      NA
#6:   17      NA
#7:   17       1
#8:   17      NA
Run Code Online (Sandbox Code Playgroud)

如果条件是使用'score.a'> 0中的所有值来子集'deid',那么上面的代码可以修改为,

setDT(help)[,  if(!all(is.na(score.a)) & 
         all(score.a[!is.na(score.a)]>0)) .SD , deid]
#   deid score.a
#1:    5      NA
#2:    5       1
#3:    5       1
#4:    5       1
#5:    5      NA
#6:   17      NA
#7:   17       1
#8:   17      NA
Run Code Online (Sandbox Code Playgroud)

假设'deid'组中的'score.a'之一小于0,

help$score.a[3] <- -1
Run Code Online (Sandbox Code Playgroud)

上面的代码会返回

 setDT(help)[,  if(!all(is.na(score.a)) & 
           all(score.a[!is.na(score.a)]>0, deid],
 #   deid score.a
 #1:   17      NA
 #2:   17       1
 #3:   17      NA
Run Code Online (Sandbox Code Playgroud)