【问题标题】:Get first and last value from groups using rle使用 rle 从组中获取第一个和最后一个值
【发布时间】:2017-08-04 16:31:43
【问题描述】:

我想使用类似于 rle() 函数所做的分组来获取组的第一个和最后一个值。

例如我有这个数据框:

> df
   df time
1   1    A
2   1    B
3   1    C
4   1    D
5   2    E
6   2    F
7   2    G
8   1    H
9   1    I
10  1    J
11  3    K
12  3    L
13  3    M
14  2    N
15  2    O
16  2    P

我想得到这样的东西:

> want
  df first last
1  1     A    D
2  2     E    G
3  1     H    J
4  3     K    M
5  2     N    P

如您所见,我想以 rle() 函数的方式对我的值进行分组。我只想在相同的值彼此相邻时对元素进行分组。 group_by 以不同的方式对元素进行分组。

> rle(df$df)
Run Length Encoding
  lengths: int [1:5] 4 3 3 3 3
  values : num [1:5] 1 2 1 3 2

我的问题有解决方案吗?任何建议将不胜感激。

【问题讨论】:

    标签: r


    【解决方案1】:

    有一个来自data.table 的函数rleid 可以完成这项工作,即

    library(data.table)
    
    setDT(dt)[, .(df = head(df, 1), 
                  first = head(time, 1), 
                  last = tail(time, 1)), 
          by = (grp = rleid(df))][, grp := NULL][]
    

    这给了,

       df first last
    1:  1     A    D
    2:  2     E    G
    3:  1     H    J
    4:  3     K    M
    5:  2     N    P
    

    添加dplyr 方法,正如@RonakShah 提到的那样

    library(dplyr)
    
    df %>% 
     group_by(grp = cumsum(c(0, diff(df)) != 0)) %>% 
     summarise(df = first(df), 
               first = first(time), 
               last = last(time)) %>% 
     select(-grp)
    

    给予,

    # A tibble: 5 x 3
         df first  last
      <int> <chr> <chr>
    1     1     A     D
    2     2     E     G
    3     1     H     J
    4     3     K     M
    5     2     N     P
    

    【讨论】:

    • 非常感谢。这正是我想要的!
    • @RonakShah 如果您使用的是dplyr,不妨使用first = first(time), last = last(time)。漂亮而清晰。
    • 第二种方法给了我一个错误:overscope_eval_next(overscope,expr)中的错误:找不到对象'grp'。你知道为什么吗?
    • 问题出在group_by。也许尝试将df 变量命名为其他名称,因为df 也是数据框的名称。
    【解决方案2】:

    这是一个使用base Rrle 的选项。一旦我们在第一列上执行rle,复制valueslengths 的序列,使用它来创建duplicated 的逻辑索引,然后根据索引对原始数据集的值进行子集化

    rl <- rle(df[,1])
    i1 <- rep(seq_along(rl$values), rl$lengths)
    i2 <- !duplicated(i1)
    i3 <- !duplicated(i1, fromLast = TRUE)
    wanted <- data.frame(df = df[i2,1], first =  df[i2,2], last = df[i3,2])
    wanted
    #   df first last
    #1  1     A    D
    #2  2     E    G
    #3  1     H    J
    #4  3     K    M
    #5  2     N    P
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-06
      • 2018-08-12
      • 2019-03-09
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多