【问题标题】:add counter column by arranging two variables (dplyr)通过排列两个变量添加计数器列(dplyr)
【发布时间】:2017-12-16 03:27:06
【问题描述】:

我在这里和那里寻找了一段时间,但我找不到适合我的情况的任何解决方案。我有一个混合了 ID 和 VAR 的数据框。下面我尝试复制一个示例

require(dplyr)
seed(123)
N <- 3
T <- 4
id <- rep(letters[1:N], each = T) 
var <- rep(sample(seq(1:100),T),N) 
row <- sample(seq(1:(N*T)),replace = F)

dt <- data.frame(ID=id,VAR=var,ROW=row) %>%
  arrange(ROW) %>%
  select(-ROW)

我想通过 ID 和 VAR arrange 并为每个组添加一个计数器以获得类似的东西

   ID VAR COUNTER
1   a   1 1
2   a  11 2
3   a  22 3
4   a  64 4
5   b   1 1
6   b  11 2
7   b  22 3
8   b  64 4
9   c   1 1
10  c  11 2
11  c  22 3
12  c  64 4

所有这一切,如果可能的话,只需使用 dplyr 或基本函数。

【问题讨论】:

    标签: r count group-by dplyr


    【解决方案1】:

    dplyr 内,您需要通过IDVARarrange(),然后group_by() 只需ID

    然后您使用mutate() 添加一个新列,从1 计数到n()(其中n() 是用于“行数”的dplyr 函数)

    set.seed(123)
    dt %>%
        arrange(ID, VAR) %>%
        group_by(ID) %>%
        mutate(COUNTER = 1:n()) %>%  ## as per comment, can use row_number()
        ungroup()
    
    # # A tibble: 12 × 3
    #         ID   VAR COUNTER
    #     <fctr> <int>   <int>
    # 1       a    29       1
    # 2       a    41       2
    # 3       a    79       3
    # 4       a    86       4
    # 5       b    29       1
    # 6       b    41       2
    # 7       b    79       3
    # 8       b    86       4
    # 9       c    29       1
    # 10      c    41       2
    # 11      c    79       3
    # 12      c    86       4
    

    关于取消分组的评论

    我这样做是为了删除与grouped_df 关联的所有“分组”属性。在此示例中,结果是相同的,但那些分组的属性可能会进一步影响您。

    dt_grouped <- dt %>%
        arrange(ID, VAR) %>%
        group_by(ID) %>%
        mutate(COUNTER = 1:n()) 
    
    dt_ungrouped <- dt %>%
        arrange(ID, VAR) %>%
        group_by(ID) %>%
        mutate(COUNTER = 1:n()) %>%
        ungroup()
    
    str(dt_grouped)
    # Classes ‘grouped_df’, ‘tbl_df’, ‘tbl’ and 'data.frame':   12 obs. of  3 variables:
    #   $ ID     : Factor w/ 3 levels "a","b","c": 1 1 1 1 2 2 2 2 3 3 ...
    # $ VAR    : int  29 41 79 86 29 41 79 86 29 41 ...
    # $ COUNTER: int  1 2 3 4 1 2 3 4 1 2 ...
    # - attr(*, "vars")=List of 1
    # ..$ : symbol ID
    # - attr(*, "labels")='data.frame': 3 obs. of  1 variable:
    #   ..$ ID: Factor w/ 3 levels "a","b","c": 1 2 3
    # ..- attr(*, "vars")=List of 1
    # .. ..$ : symbol ID
    # ..- attr(*, "drop")= logi TRUE
    # - attr(*, "indices")=List of 3
    # ..$ : int  0 1 2 3
    # ..$ : int  4 5 6 7
    # ..$ : int  8 9 10 11
    # - attr(*, "drop")= logi TRUE
    # - attr(*, "group_sizes")= int  4 4 4
    # - attr(*, "biggest_group_size")= int 4
    
    str(dt_ungrouped)
    # Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 12 obs. of  3 variables:
    #   $ ID     : Factor w/ 3 levels "a","b","c": 1 1 1 1 2 2 2 2 3 3 ...
    # $ VAR    : int  29 41 79 86 29 41 79 86 29 41 ...
    # $ COUNTER: int  1 2 3 4 1 2 3 4 1 2 ...
    

    【讨论】:

    • 1:n() 的替代方案:row_number()
    • @SymbolixAU,你为什么在代码末尾使用ungroup?我没有使用它得到了相同的结果。
    • 非常感谢!!在此之前,我以不同的方式组合了 3 个函数,只是忘记了你的:arrange、group_by 和 mutate。
    猜你喜欢
    • 2022-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2015-10-11
    • 2021-01-01
    • 1970-01-01
    相关资源
    最近更新 更多