【问题标题】:R conditional grouping of rows and numbering of groupsR条件分组行和组编号
【发布时间】:2015-09-07 10:55:46
【问题描述】:

我使用用于飞行运动的数据帧(约 100 万行 * 108 个变量)并希望对满足某个标准(即某个变量的值)的阶段进行分组。为了识别这些组,我想给它们编号。 作为一个 R 新手,我让它适用于我的情况。现在我正在寻找一种更优雅的方式。特别是,我想克服组编号中的“无用”空白。 我提供了一个简化的 dplyr 数据框示例,其阈值标准的值为 THR。行按时间戳排序(因此,我可以在这里截断它)。

THR <- c(13,17,19,22,21,19,17,12,12,17,20,20,20,17,17,13, 20,20,17,13)
df  <- as.data.frame(THR)
df  <- tbl_df(df)

标记所有符合(不)条件的行

df  <- mutate(df, CRIT = THR < 19)

通过以下,我设法有条件地“cumsum”以获得唯一的组标识:

df <- mutate(df, GRP = ifelse(CRIT == 1, 0, cumsum(CRIT))
df
    x CRIT GRP
1  13 TRUE   0
2  17 TRUE   0
3  19 FALSE  2          
4  22 FALSE  2
5  21 FALSE  2
6  19 FALSE  2
7  17 TRUE   0
8  12 TRUE   0
9  12 TRUE   0
10 17 TRUE   0
11 20 FALSE  6
12 20 FALSE  6

虽然这样做可以解决问题,并且我可以使用 group_by(例如 summarise、filter)对组进行操作,但从示例输出中可以看出,编号并不理想。在本例中,第 1 组编号为 2,第 2 组编号为 6,这与 cumsum() 结果一致。

如果有人能对我有所了解,我将不胜感激。我无法在其他帖子中找到合适的解决方案。

【问题讨论】:

    标签: r grouping


    【解决方案1】:

    我不知道你真的可以避免创建CRIT 的初步步骤,尽管我建议在创建它时添加cumsum 然后运行一个简单的cumsum/diff 结束它.此外,如果您不需要不符合条件的组,最好分配NA 而不是仅分配一些随机数,例如零。这是一个可能的data.table 总结(另外,您根本不需要df &lt;- tbl_df(df) 步骤)

    library(data.table)
    setDT(df)[, CRIT := cumsum(THR < 19)]
    df[THR >= 19, GRP := cumsum(c(0L, diff(CRIT)) != 0L) + 1L]
    #     THR CRIT GRP
    #  1:  13    1  NA
    #  2:  17    2  NA
    #  3:  19    2   1
    #  4:  22    2   1
    #  5:  21    2   1
    #  6:  19    2   1
    #  7:  17    3  NA
    #  8:  12    4  NA
    #  9:  12    5  NA
    # 10:  17    6  NA
    # 11:  20    6   2
    # 12:  20    6   2
    # 13:  20    6   2
    # 14:  17    7  NA
    # 15:  17    8  NA
    # 16:  13    9  NA
    # 17:  20    9   3
    # 18:  20    9   3
    # 19:  17   10  NA
    # 20:  13   11  NA
    

    【讨论】:

    • 感谢您的解决方案。这也很好用。我将采用上述上校的解决方案,因为我(暂时)想坚持使用基础 R 和 dplyr。我会将 data.table 包保留在我的圣诞假期待办事项列表中。
    【解决方案2】:

    你可以这样做:

     x = rle(df$CRIT)
     mask = x$values
     x$values[mask] = 0
     x$values[!mask] = cumsum(!x$values[!mask])
    
     mutate(df, GRP=inverse.rle(x))
    
    #   THR  CRIT GRP
    #1   13  TRUE   0
    #2   17  TRUE   0
    #3   19 FALSE   1
    #4   22 FALSE   1
    #5   21 FALSE   1
    #6   19 FALSE   1
    #7   17  TRUE   0
    #8   12  TRUE   0
    #9   12  TRUE   0
    #10  17  TRUE   0
    #11  20 FALSE   2
    #12  20 FALSE   2
    #13  20 FALSE   2
    #14  17  TRUE   0
    #15  17  TRUE   0
    #16  13  TRUE   0
    #17  20 FALSE   3
    #18  20 FALSE   3
    #19  17  TRUE   0
    #20  13  TRUE   0
    

    【讨论】:

    • ;) ...谢谢你。它工作得很好,我能够了解一个我还不知道的函数:rle()。我需要弄清楚 x$values[!mask] = cumsum(!x$values[!mask]) 的作用。但这更像是一个新手问题,而不是解决方案的问题。
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多