【问题标题】:Slicing using dplyr based on condition in a column根据列中的条件使用 dplyr 进行切片
【发布时间】:2021-09-09 08:43:40
【问题描述】:

我有一个数据框,其中包含对某些人的重复测量,data.frame 看起来像这样

# A tibble: 853 x 5
   ID         Test  N_ind Pheno  Week
   <chr>      <chr> <int> <dbl> <int>
 1 02A01      Int      96     0    12
 2 02A01      Int      96     0    24
 3 02A01      Int      94     0    36
 4 02A01      Int      90     0    48
 7 02A01      Int      78     1    84
 9 02A03      Int      96     0    12
10 02A03      Int      96     0    24
11 02A03      Int      94     0    36
19 02C03      Int      96     1    12
20 0202C03    Int      96     0    24
21 0202C03    Int      94     0    36
22 0202C03    Int      90     0    48
23 02E02      Int      96     0    12
24 02E02      Int      96     0    24
25 02E02      Int      94     1    36
26 02E02      Int      90     1    48

我想对 data.frame 进行子集化,首先按ID 分组,然后在组中选择Pheno 列中1 具有最低Week 值的那些人,但对于那些具有0Pheno 列中的Week 中的最大值。

最佳结果应如下所示:

   ID         Test  N_ind Pheno  Week
   <chr>      <chr> <int> <dbl> <int>
 7 02A01      Int      78     1    84
11 02A03      Int      94     0    36
19 02C03      Int      96     1    12
22 0202C03    Int      90     0    48
25 02E02      Int      94     1    36

我已经设法为1 值做到这一点,但我被困在如何为0 值做到这一点。

这是我的代码:

df_sub <- data %>% 
  group_by(ID) %>%
  arrange(Week, .by_group = TRUE) %>%
  ungroup()

任何帮助将不胜感激

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你可以试试-

    library(dplyr)
    
    data %>%
      group_by(ID) %>%
      filter(Week == if(all(Pheno == 0)) max(Week) else min(Week[Pheno == 1])) %>%
      ungroup
    
    #   ID      Test  N_ind Pheno  Week
    #  <chr>   <chr> <int> <int> <int>
    #1 02A01   Int      78     1    84
    #2 02A03   Int      94     0    36
    #3 02C03   Int      96     1    12
    #4 0202C03 Int      90     0    48
    #5 02E02   Int      94     1    36
    

    如果 all 组中的 Pheno 值为 0,则返回最大值,否则从 Pheno = 1 值返回最小值。

    【讨论】:

    • 太棒了!!我不知道我可以在filter 中使用ifelse 命令,谢谢!!
    【解决方案2】:

    filter 中使用dplyrifelse

    df %>%
      group_by(ID) %>%
      filter(if (Pheno == 0) Week == max(Week)
             else Week == min(Week))
    
      ID      Test  N_ind Pheno  Week
      <chr>   <chr> <dbl> <dbl> <dbl>
    1 02A01   Int      78     1    84
    2 02A03   Int      94     0    36
    3 02C03   Int      96     1    12
    4 0202C03 Int      90     0    48
    5 02E02   Int      90     1    48
    

    【讨论】:

      【解决方案3】:

      我们可以先group_by ID,然后filter 使用 Pheno 中的max 值。 之后,我们可以使用您想要的条件进行过滤,用 OR | 语句分隔。

      library(dplyr)
      
      df %>% group_by(ID) %>%
              filter(Pheno==max(Pheno))%>%
              filter(Pheno==0 & Week==min(Week)|Pheno==1 & Week==max(Week))
      
      # A tibble: 5 x 5
      # Groups:   ID [5]
        ID      Test  N_ind Pheno  Week
        <chr>   <chr> <int> <int> <int>
      1 02A01   Int      78     1    84
      2 02A03   Int      96     0    12
      3 02C03   Int      96     1    12
      4 0202C03 Int      96     0    24
      5 02E02   Int      90     1    48
      

      【讨论】:

        【解决方案4】:

        这是我想出的:

        data %>%
          group_by(ID, Pheno) %>%
          filter(case_when(
            Pheno == 1 ~ Week == min(Week),
            Pheno == 0 ~ Week == max(Week)
          )) %>%
          ungroup(Pheno) %>%
          filter(case_when(
            any(Pheno == 1) ~ Pheno == 1,
            all(Pheno == 0) ~ Pheno == 0
          )) %>%
          ungroup()
        

        哪些结果:

        # A tibble: 5 x 5
          ID      Test  N_ind Pheno  Week
          <chr>   <chr> <int> <int> <int>
        1 02A01   Int      78     1    84
        2 02A03   Int      94     0    36
        3 02C03   Int      96     1    12
        4 0202C03 Int      90     0    48
        5 02E02   Int      94     1    36
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-07
          • 2022-11-14
          • 1970-01-01
          • 2020-06-25
          • 1970-01-01
          • 2018-01-21
          • 2016-12-30
          • 1970-01-01
          相关资源
          最近更新 更多