忽略dplyr

时间:2019-05-09 14:21:09

标签: r dplyr

我有一个数据框,例如:

> tab
   Groups Species Value
1  Group1     Sp1     1
2  Group1     Sp1     4
3  Group1     Sp2    78
4  Group1     Sp3    NA
5  Group1     Sp4    NA
6  Group2     Sp2     3
7  Group2     Sp3     9
8  Group2     Sp4     8
9  Group3     Sp1     9
10 Group3     Sp3    10
11 Group3     Sp3   110
12 Group3     Sp3    14

并且我正在尝试将值<80

保留在组中

我尝试过:

tab %>%
  group_by(Groups) %>%
    filter(all(Value < 80))

但是我不知道如何忽略过滤器中的NA values

在这里我应该得到:

> tab
   Groups Species Value
1  Group1     Sp1     1
2  Group1     Sp1     4
3  Group1     Sp2    78
4  Group1     Sp3    NA
5  Group1     Sp4    NA
6  Group2     Sp2     3
7  Group2     Sp3     9
8  Group2     Sp4     8

有人可以解决吗? 谢谢

如果我也有:

> tab
   Groups Species Value sp mrca
1  Group1     Sp1     1  3    3
2  Group1     Sp1     4  3    3
3  Group1     Sp2    78 NA   NA
4  Group1     Sp3    NA  3   12
5  Group1     Sp4    NA  3    3
6  Group2     Sp2     3  2    3
7  Group2     Sp3     9  2    40
8  Group2     Sp4     8 NA   NA
9  Group3     Sp1     9  2    2
10 Group3     Sp3    10  3    3
11 Group3     Sp3   110  3    2
12 Group3     Sp3    14  2    3

我想过滤所有具有<80个值的组,并且其中sp-mrca = 0:9

我试过了你的答案:

tab %>%
  group_by(Groups) %>%
  filter(all(Value < 80 |is.na(Value))) %>%
  filter((all(abs(sp - mrca) %in% 0:9)|is.na(sp) & is.na(mrca)))

但这似乎不是正确的代码

我应该得到:

> tab
   Groups Species Value sp mrca
1  Group1     Sp1     1  3    3
2  Group1     Sp1     4  3    3
3  Group1     Sp2    78 NA   NA
4  Group1     Sp3    NA  3   12
5  Group1     Sp4    NA  3    3

2 个答案:

答案 0 :(得分:3)

我们可以将|is.na一起使用

tab %>%
    group_by(Groups) %>%
    filter(all(Value < 80 |is.na(Value)))
# A tibble: 8 x 3
# Groups:   Groups [2]
#  Groups Species Value
#  <chr>  <chr>   <int>
#1 Group1 Sp1         1
#2 Group1 Sp1         4
#3 Group1 Sp2        78
#4 Group1 Sp3        NA
#5 Group1 Sp4        NA
#6 Group2 Sp2         3
#7 Group2 Sp3         9
#8 Group2 Sp4         8

OP代码中的问题在于,当我们用all包装Value < 80时,比较返回NA的那些值NA和现在的{{1} }还会返回all而不是逻辑TRUE / FALSE,并且在NA中,它会默认自动删除filter

为更好地理解,请检查输出

NA

和这里的区别

tab %>% 
    group_by(Groups) %>% 
    mutate(ind = all(Value < 80))

或使用tab %>% group_by(Groups) %>% mutate(ind = all(Value < 80| is.na(Value)))

data.table

或使用library(data.table) setDT(tab)[, .SD[all(Value < 80 | is.na(Value))], Groups]

base R

更新

对于第二个数据集,

tab[with(tab, ave(Value < 80  | is.na(Value), Groups, FUN = all)),]

数据

tab1 %>% 
    group_by(Groups) %>%
    filter(all(Value < 80 |is.na(Value)),
           all(na.omit(abs(sp-mrca)) %in% 0:9))

答案 1 :(得分:1)

我们可以将基数R中的avesubset一起使用。从数据中删除NA行,并找到具有all值小于80的组,并从原始subset中找到tab的组

subset(tab, Groups %in% unique(with(na.omit(tab), 
            Groups[ave(Value < 80, Groups, FUN = all)])))

#  Groups Species Value
#1 Group1     Sp1     1
#2 Group1     Sp1     4
#3 Group1     Sp2    78
#4 Group1     Sp3    NA
#5 Group1     Sp4    NA
#6 Group2     Sp2     3
#7 Group2     Sp3     9
#8 Group2     Sp4     8