【问题标题】:How to get every nth element from each group in a grouped data frame如何从分组数据框中的每个组中获取每个第 n 个元素
【发布时间】:2019-11-25 17:42:47
【问题描述】:

我有一个大数据框,其中有一列,带有一个组名,它与 dplyr 分组。所以多行具有相同的组名。为了减少数据,我想从每组的第一个元素开始提取每个第 n 个元素。有没有没有循环的R方式

用一个序列对每一行进行子集化,问题是每组的第一行经常被遗漏。例如

data[seq(1, nrow(data), 10), ] # Some groups start without the first row.

输入:

   Val Group
1  1.0 Fruit
2  2.0 Fruit
3  3.0 Fruit
4  1.5 Veg
5  2.8 Veg
6  4.2 Veg
7  5.1 Veg

输出(每隔一个元素,注意第三行!):

   Val Group
1  1.0 Fruit
2  3.0 Fruit
**3  1.5 Veg**
4  4.2 Veg

【问题讨论】:

    标签: r dataframe filter dplyr grouping


    【解决方案1】:
    library(dplyr)
    data %>% group_by(Group) %>%
      slice(seq(1, n(), by = 2))
    

    这给出:

    # A tibble: 4 x 2
    # Groups:   Group [2]
        Val Group
      <dbl> <fct>
    1   1   Fruit
    2   3   Fruit
    3   1.5 Veg  
    4   4.2 Veg 
    

    【讨论】:

    • 或者使用计数器 - dat %&gt;% group_by(Group) %&gt;% filter(row_number() %% 2 == 1) ,在大数据上应该会快一点。
    【解决方案2】:

    这是一个基本的 R 方式:

    DF$ID_by_Group <- ave(DF$Val, DF$Group, FUN =  seq_along)
    DF[DF$ID_by_Group %in% seq(1,3, by = 2), ]
    
      Val Group ID_by_Group
    1 1.0 Fruit           1
    3 3.0 Fruit           3
    4 1.5   Veg           1
    6 4.2   Veg           3
    

    ave() 函数按组创建 ID。第二个语句只是根据我们创建的ID_by_Group 进行过滤。

    注意,我们可以一次完成所有操作和/或删除添加的列:

    DF[ave(DF$Val, DF$Group, FUN =  seq_along) %in% seq(1,3, by = 2), ]
    
    DF$ID_by_Group <- ave(DF$Val, DF$Group, FUN =  seq_along)
    
    DF[DF$ID_by_Group %in% seq(1,3, by = 2), -3]
    DF[DF$ID_by_Group %in% seq(1,3, by = 2), -grep('ID_by_Group', names(DF))]
    DF[DF$ID_by_Group %in% seq(1,3, by = 2), c('Val', 'Group')]
    
    #all provide:
    
      Val Group
    1 1.0 Fruit
    3 3.0 Fruit
    4 1.5   Veg
    6 4.2   Veg
    

    【讨论】:

      【解决方案3】:

      另一种选择是data.table

      > setDT(data)                   
      > data[(rowid(Group) %% 2) == 1]
         Val Group                    
      1: 1.0 Fruit                    
      2: 3.0 Fruit                    
      3: 1.5   Veg                    
      4: 4.2   Veg                    
      

      【讨论】:

        【解决方案4】:

        另一个基本 R 选项,用于使用 ave 探索回收属性选择每组中的每 n 行

        n <- 2
        
        df[as.logical(with(df, ave(Val, Group, FUN = function(x) 
                              c(TRUE, rep(FALSE, n - 1))))),  ]
        
        #  Val Group
        #1 1.0 Fruit
        #3 3.0 Fruit
        #4 1.5   Veg
        #6 4.2   Veg
        

        这会返回一条警告消息,因为返回的向量长度不同,但我认为可以忽略它。

        或者使用@thelatemail 的想法从没有给出警告信息的评论中。

        df[as.logical(with(df, ave(Val, Group, FUN = function(x) 
                           seq_along(x) %% 2 == 1))), ]
        

        【讨论】:

          猜你喜欢
          • 2021-10-05
          • 2020-07-21
          • 2020-11-03
          • 2011-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-04
          • 2021-12-22
          相关资源
          最近更新 更多