【问题标题】:Subseting data frame based on multiple criteria for deletion of rows基于删除行的多个标准子集数据框
【发布时间】:2020-03-30 07:52:42
【问题描述】:

考虑以下由列名“id”和“x”组成的数据框,其中每个 id 重复四次。数据如下:

df<-data.frame("id"=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4),
                "x"=c(2,2,1,1,2,3,3,3,1,2,2,3,2,2,3,3))

问题是关于如何按以下标准对数据框进行子集化:

(1) 保留每个 id 的所有条目,如果它在 x 列中的对应值不包含 3 或它的最后一个数字为 3。

(2) 对于在 x 列中具有多个 3 的给定 id,将所有数字保留到前 3 并删除剩余的 3。预期的输出如下所示:

   id x
1   1 2
2   1 2
3   1 1
4   1 1
5   2 2
6   2 3
7   3 1
8   3 2
9   3 2
10  3 3
11  4 2
12  4 2
13  4 3 

我熟悉使用 dplyr 包中的“过滤器”功能来对数据进行子集化,但由于上述标准的复杂性,这种特殊情况让我感到困惑。对此的任何帮助将不胜感激。

【问题讨论】:

    标签: r dataframe filter subset


    【解决方案1】:

    这是一种使用/创建一些新列来帮助您过滤的解决方案:

    library(dplyr)
    
    df<-data.frame("id"=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4),
                   "x"=c(2,2,1,1,2,3,3,3,1,2,2,3,2,2,3,3))
    
    df %>%
      group_by(id) %>%                                    # for each id
      mutate(num_threes = sum(x == 3),                    # count number of 3s
             flag = ifelse(unique(num_threes) > 0,        # if there is a 3
                            min(row_number()[x == 3]),    # keep the row of the first 3
                            0)) %>%                       # otherwise put a 0
      filter(num_threes == 0 | row_number() <= flag) %>%  # keep ids with no 3s or up to first 3
      ungroup() %>%
      select(-num_threes, -flag)                          # remove helpful columns
    
    # # A tibble: 13 x 2
    #      id     x
    #   <dbl> <dbl>
    # 1     1     2
    # 2     1     2
    # 3     1     1
    # 4     1     1
    # 5     2     2
    # 6     2     3
    # 7     3     1
    # 8     3     2
    # 9     3     2
    # 10    3     3
    # 11    4     2
    # 12    4     2
    # 13    4     3
    

    【讨论】:

      【解决方案2】:

      这对我有用:

      数据

      df<-data.frame("id"=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4),
                      "x"=c(2,2,1,1,2,3,3,3,1,2,2,3,2,2,3,3))
      

      命令

      library(dplyr)
      df <- mutate(df, before = lag(x))
      
      df$condition1 <- 1
      
      df$condition1[df$x == 3 & df$before == 3] <- 0
      final_df <- df[df$condition1 == 1, 1:2]
      

      结果

          x  id
          1   2
          1   2
          1   1
          1   1
          2   2
          2   3
          3   1
          3   2
          3   2
          3   3
          4   2
          4   2
          4   3`
      

      【讨论】:

        【解决方案3】:

        一个想法是选择带有x==3 的行并在它们上面使用unique()。然后将仅带有单个 3 的唯一行附加到数据框的其余部分,最后对行进行排序。

        这里是base R 针对上述想法的解决方案:

        res <- (r <- with(df,rbind(df[x!=3,],unique(df[x==3,]))))[order(as.numeric(rownames(r))),]
        rownames(res) <- seq(nrow(res))
        

        给了

        > res
           id x
        1   1 2
        2   1 2
        3   1 1
        4   1 1
        5   2 2
        6   2 3
        7   3 1
        8   3 2
        9   3 2
        10  3 3
        11  4 2
        12  4 2
        13  4 3
        

        数据

        df<-data.frame("id"=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4),
                       "x"=c(2,2,1,1,2,3,3,3,1,2,2,3,2,2,3,3))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-06
          • 2016-03-19
          • 2021-08-04
          • 1970-01-01
          相关资源
          最近更新 更多