如何按各个因素水平过滤对象?

时间:2020-07-01 19:43:45

标签: r filter dplyr tidyverse

我正在尝试过滤数据集,以仅包括在所有条件(因子水平)下具有数据的受试者。

我试图通过计算每个主题的级别数进行过滤,但这是行不通的。

library(tidyverse)
Data <- data.frame(
        Subject = factor(c(rep(1, 3),
                           rep(2, 3),
                           rep(3, 1))),
        Condition = factor(c("A", "B", "C",
                             "A", "B", "C",
                             "A")),
        Val = c(1, 0, 1,
                0, 0, 1,
                1)
)

Data %>%
        semi_join(
                .,
                Data %>%
                        group_by(Subject) %>%
                        summarize(Num_Cond = length(levels(Condition))) %>%
                filter(Num_Cond == 3),
                by = "Subject"
        )

此尝试产生:

  Subject Condition Val
1       1         A   1
2       1         B   0
3       1         C   1
4       2         A   0
5       2         B   0
6       2         C   1
7       3         A   1

所需的输出:

  Subject Condition Val
1       1         A   1
2       1         B   0
3       1         C   1
4       2         A   0
5       2         B   0
6       2         C   1

我想过滤掉主题3,因为它们只有一种情况的数据。

是否有针对这个问题的dplyr / tidyverse方法?

3 个答案:

答案 0 :(得分:2)

我们可以使用>#all

创建条件
levels

或者使用library(dplyr) Data %>% group_by(Subject) %>% filter(all(levels(Condition) %in% Condition)) # A tibble: 6 x 3 # Groups: Subject [2] # Subject Condition Val # <fct> <fct> <dbl> #1 1 A 1 #2 1 B 0 #3 1 C 1 #4 2 A 0 #5 2 B 0 #6 2 C 1 n_distinct

nlevels

答案 1 :(得分:1)

这是一个解决方案,用于测试每个组的行数是否等于Condition的级别数。

Data %>%
  group_by(Subject) %>%
  filter(n() == nlevels(Condition))
## A tibble: 6 x 3
## Groups:   Subject [2]
#  Subject Condition   Val
#  <fct>   <fct>     <dbl>
#1 1       A             1
#2 1       B             0
#3 1       C             1
#4 2       A             0
#5 2       B             0
#6 2       C             1

编辑

根据用户@akrun的评论,我测试了一个数据集,该数据集的每一行都有重复的值,并且上面的代码确实失败了。

bind_rows(Data, Data) %>%
  group_by(Subject) %>%
  #distinct() %>%
  filter(n() == nlevels(Condition))
## A tibble: 0 x 3
## Groups:   Subject [0]
## ... with 3 variables: Subject <fct>, Condition <fct>, Val <dbl>

运行注释掉的代码行将解决问题。

答案 2 :(得分:0)

我通过对Subject进行子设置找到了一个相对简单的解决方案:

Data %>%
        semi_join(
                .,
                Data %>%
                        group_by(Subject) %>%
                        droplevels() %>%
                        summarize(Num_Cond = length(levels(Condition)[Subject])) %>%
                filter(Num_Cond == 3),
                by = "Subject"
        )

这将提供所需的输出:

  Subject Condition Val
1       1         A   1
2       1         B   0
3       1         C   1
4       2         A   0
5       2         B   0
6       2         C   1
相关问题