【问题标题】:R: subset dataframe for all rows after a condition is metR:满足条件后所有行的子集数据帧
【发布时间】:2020-12-25 04:32:07
【问题描述】:

所以我有以下形式的数据集:

ID    Var1   Var2
1      2      0
1      8      0
1      12     0
1      11     1
1      10     1
2      5      0
2      8      0
2      7      0
2      6      1
2      5      1

我想对数据框进行子集化并创建一个新的数据框,仅包含 Var1 首次达到其组最大值之后的行(包括发生这种情况的行)直到 Var2 第一次变为 1 的行(还包括这一行)。所以我想要的应该是这样的:

ID    Var1   Var2
1      12     0
1      11     1
2      8      0
2      7      0
2      6      1

原始数据集包含许多 NA,函数应该简单地忽略这些。此外,如果组的 Var2 从未达到“1”,则应该将所有行添加到新数据帧(当然只有 Var1 达到其组最大值之后的行)。 但是,我无法绕过编程。有人知道帮忙吗?

【问题讨论】:

    标签: r dplyr subset


    【解决方案1】:

    cumsum 基于filterdplyr 解决方案将满足问题的要求。

    library(dplyr)
    
    df1 %>%
      group_by(ID) %>%
      filter(cumsum(Var1 == max(Var1)) == 1, cumsum(Var2) <= 1)
    ## A tibble: 5 x 3
    ## Groups:   ID [2]
    #     ID  Var1  Var2
    #  <int> <int> <int>
    #1     1    12     0
    #2     1    11     1
    #3     2     8     0
    #4     2     7     0
    #5     2     6     1
    

    编辑

    这是一个尝试回答 OP 的评论和问题编辑的解决方案。

    df1 %>%
      group_by(ID) %>%
      mutate_at(vars(starts_with('Var')), ~replace_na(., 0L)) %>%
      filter(cumsum(Var1 == max(Var1)) == 1, cumsum(Var2) <= 1)
    

    数据

    df1 <- read.table(text = "
    ID    Var1   Var2
    1      2      0
    1      8      0
    1      12     0
    1      11     1
    1      10     1
    2      5      0
    2      8      0
    2      7      0
    2      6      1
    2      5      1
    ", header = TRUE)
    

    【讨论】:

    • 非常感谢您的回答。但是,这在实际数据集上并不是 100% 有效。对于大多数组来说,只剩下一行,这是不可能的。解决方案如何处理 NA 以及 Var2 中是否没有“1”?我刚刚编辑了问题以使其更清楚
    • @philipp.kn_98 查看编辑中的解决方案是否回答了问题。
    【解决方案2】:

    这是data.table Rui Barradas 工作解决方案的翻译:

    library(data.table)
    
    dat <- fread(text = "
    ID    Var1   Var2
    1      2      0
    1      8      0
    1      12     0
    1      11     1
    1      10     1
    2      5      0
    2      8      0
    2      7      0
    2      6      1
    2      5      1
    ", header = TRUE)
    
    dat[, .SD[cumsum(Var1 == max(Var1)) & cumsum(Var2) <= 1], by="ID"]
    
    

    【讨论】:

      【解决方案3】:

      data.table.I 一起使用

      library(data.table)
      setDT(df1)[df1[, .I[cumsum(Var1 == max(Var1)) & cumsum(Var2) <= 1], by="ID"]$V1]
      #   ID Var1 Var2
      #1:  1   12    0
      #2:  1   11    1
      #3:  2    8    0
      #4:  2    7    0
      #5:  2    6    1
      

      数据

      df1 <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), 
          Var1 = c(2L, 8L, 12L, 11L, 10L, 5L, 8L, 7L, 6L, 5L), Var2 = c(0L, 
          0L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 1L)), class = "data.frame",
          row.names = c(NA, 
      -10L))
      

      【讨论】:

        猜你喜欢
        • 2023-01-25
        • 2021-06-09
        • 1970-01-01
        • 1970-01-01
        • 2016-12-04
        • 2013-08-07
        • 2021-05-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多