【问题标题】:How can I filter by subjects who have all levels of a factor?如何按具有所有级别因子的主题进行过滤?
【发布时间】:2020-10-22 08:10:36
【问题描述】:

我正在尝试过滤数据集以仅包含在所有条件下(因子级别)都有数据的受试者。

我尝试通过计算每个主题的级别数来进行过滤,但这不起作用。

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 方法?

【问题讨论】:

    标签: r filter dplyr tidyverse


    【解决方案1】:

    我们可以用alllevels创建条件

    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_distinctnlevels

    Data %>% 
        group_by(Subject) %>% 
        filter(nlevels(Condition) == n_distinct(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
    

    【讨论】:

    • 不错!我不知道all。非常简单和优雅的解决方案。谢谢!
    【解决方案2】:

    这是一个测试每个组的行数是否等于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>
    

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

    【讨论】:

      【解决方案3】:

      我通过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
      

      【讨论】:

        猜你喜欢
        • 2015-02-24
        • 1970-01-01
        • 1970-01-01
        • 2015-01-05
        • 2020-11-29
        • 1970-01-01
        • 1970-01-01
        • 2013-07-25
        • 2012-08-26
        相关资源
        最近更新 更多