【问题标题】:R tidyverse: create groups based on index columnR tidyverse:根据索引列创建组
【发布时间】:2020-09-08 04:57:07
【问题描述】:

我有这个小标题

# Data
set.seed(1)
x <- tibble(values = round(rnorm(20, 10, 10), 0),
            index = c(0,0,1,1,1,0,1,0,1,1,1,1,1,1,0,
                      1,1,0,0,0))
x
#> # A tibble: 20 x 2
#>    values index
#>     <dbl> <dbl>
#>  1      4     0
#>  2     12     0
#>  3      2     1
#>  4     26     1
#>  5     13     1
#>  6      2     0
#>  7     15     1
#>  8     17     0
#>  9     16     1
#> 10      7     1
#> 11     25     1
#> 12     14     1
#> 13      4     1
#> 14    -12     1
#> 15     21     0
#> 16     10     1
#> 17     10     1
#> 18     19     0
#> 19     18     0
#> 20     16     0

我想创建索引列中的值是连续值的组。最终目标是计算每个组的总和。

这是预期的小标题,类似于:

# A tibble: 20 x 3
   values index group
    <dbl> <dbl> <chr>
 1      4     0 NA   
 2     12     0 NA   
 3      2     1 A    
 4     26     1 A    
 5     13     1 A    
 6      2     0 NA   
 7     15     1 B    
 8     17     0 NA   
 9     16     1 C    
10      7     1 C    
11     25     1 C    
12     14     1 C    
13      4     1 C    
14    -12     1 C    
15     21     0 NA   
16     10     1 D    
17     10     1 D    
18     19     0 NA   
19     18     0 NA   
20     16     0 NA 

提前感谢您的建议。

【问题讨论】:

    标签: r tidyverse data-wrangling


    【解决方案1】:

    您可以在由rle() 标识的运行中使用cumsum(),将索引为零的值替换为NA。如果 ID 超过 26 个,则需要稍作修改。

    library(dplyr)
    
    x2 <- x %>%
      mutate(id = LETTERS[replace(with(rle(index),
                                       rep(cumsum(values), lengths)), index == 0, NA)])
    

    给予:

    # A tibble: 20 x 3
       values index id   
        <dbl> <dbl> <chr>
     1      4     0 NA   
     2     12     0 NA   
     3      2     1 A    
     4     26     1 A    
     5     13     1 A    
     6      2     0 NA   
     7     15     1 B    
     8     17     0 NA   
     9     16     1 C    
    10      7     1 C    
    11     25     1 C    
    12     14     1 C    
    13      4     1 C    
    14    -12     1 C    
    15     21     0 NA   
    16     10     1 D    
    17     10     1 D    
    18     19     0 NA   
    19     18     0 NA   
    20     16     0 NA
    

    总结价值:

    x2 %>%
      group_by(id) %>%
      summarise(sv = sum(values))
    
    # A tibble: 5 x 2
      id       sv
    * <chr> <dbl>
    1 A        41
    2 B        15
    3 C        54
    4 D        20
    5 NA      109
    

    【讨论】:

      【解决方案2】:

      data.table 的选项

      library(data.table)
      setDT(x)[, group :=  LETTERS[as.integer(factor((NA^!index) *rleid(index)))]]
      x
      #    values index group
      # 1:      4     0  <NA>
      # 2:     12     0  <NA>
      # 3:      2     1     A
      # 4:     26     1     A
      # 5:     13     1     A
      # 6:      2     0  <NA>
      # 7:     15     1     B
      # 8:     17     0  <NA>
      # 9:     16     1     C
      #10:      7     1     C
      #11:     25     1     C
      #12:     14     1     C
      #13:      4     1     C
      #14:    -12     1     C
      #15:     21     0  <NA>
      #16:     10     1     D
      #17:     10     1     D
      #18:     19     0  <NA>
      #19:     18     0  <NA>
      #20:     16     0  <NA>
      

      或者dplyr中的类似逻辑

      library(dplyr)
      x %>% 
        mutate(group = LETTERS[as.integer(factor((NA^!index) *rleid(index)))])
      # A tibble: 20 x 3
      #   values index group
      #    <dbl> <dbl> <chr>
      # 1      4     0 <NA> 
      # 2     12     0 <NA> 
      # 3      2     1 A    
      # 4     26     1 A    
      # 5     13     1 A    
      # 6      2     0 <NA> 
      # 7     15     1 B    
      # 8     17     0 <NA> 
      # 9     16     1 C    
      #10      7     1 C    
      #11     25     1 C    
      #12     14     1 C    
      #13      4     1 C    
      #14    -12     1 C    
      #15     21     0 <NA> 
      #16     10     1 D    
      #17     10     1 D    
      #18     19     0 <NA> 
      #19     18     0 <NA> 
      #20     16     0 <NA> 
      

      【讨论】:

        猜你喜欢
        • 2022-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-30
        • 2013-02-12
        • 2021-02-02
        • 2020-11-19
        • 1970-01-01
        相关资源
        最近更新 更多