【问题标题】:How to give numbers to each group of a dataframe with dplyr::group_by? [duplicate]如何使用 dplyr::group_by 为数据帧的每一组赋予数字? [复制]
【发布时间】:2016-07-01 20:18:26
【问题描述】:

我想为数据框中的每个组分配数字。例如,我有以下数据框:

df = data.frame( from = c('a', 'a', 'b'), dest = c('b', 'c', 'd') )
#> df
    #from dest
#1    a    b
#2    a    c
#3    b    d

我想按from 值进行分组,并为每个组指定一个组号。这是预期的结果:

result = data.frame( from = c('a', 'a', 'b'), dest = c('b', 'c', 'd'), group_no = c(1,1,2) )
#> result
    #from dest group_no
#1    a    b        1
#2    a    c        1
#3    b    d        2

我可以使用如下的for循环来解决这个问题:

groups = df$from %>% unique
i = 0
df$group_no = NA
for ( g in groups ) {
    i = i + 1
    df[ df$from == g, ]$group_no = i
}
#> df
    #from dest group_no
#1    a    b        1
#2    a    c        1
#3    b    d        2

我想知道是否可以在不使用 for 循环的情况下以更优雅和更实用的方式解决这个问题?具体来说,我想知道这是否可以使用dplyr::group_by函数来完成?

【问题讨论】:

    标签: r group-by functional-programming dplyr


    【解决方案1】:

    你可以试试基础包中的transform

    transform(df,group_no=as.numeric(factor(from)))
    
    #   from dest group_no
    #1    a    b  1
    #2    a    c  1
    #3    b    d  2
    

    如果from 列已经是一个因素,您可以删除factor() 函数并仅使用

    transform(df,id=as.numeric(from))
    

    【讨论】:

      【解决方案2】:

      使用mutate 添加一个只是from 的数字形式的列作为因子:

      df %>% mutate(group_no = as.integer(factor(from)))
      
      #   from dest group_no
      # 1    a    b        1
      # 2    a    c        1
      # 3    b    d        2
      

      注意group_by 在此处不是必需的,除非您将其用于其他目的。如果要按新列分组以备后用,可以使用group_by 而不是mutate 来添加列。

      【讨论】:

      • 根本不需要使用group_by。 df %>% mutate(group_no=as.integer(from)) OP走错方向了。
      • 正在编辑以提及您评论...
      • 考虑使用fct_inorder() 或另一个fct_ 函数来指定因子顺序,而不是factor()。 fct_inorder() 保持数据帧的原始顺序,而因子选择但因子是有序的(可能是按字母顺序)
      • 如果您愿意,您可以按照forcats::fct_inorder(x) 和factor(x, levels = unique(x)) 之类的向量顺序创建组,但这不是问题的一部分。一般来说,行顺序没有任何意义,并且通常不能保证,除非您首先明确排序。如果您要创建一个具有一个因子的因子(而不是像这里那样创建索引),您需要以某种方式指定级别。
      【解决方案3】:

      我们可以从dplyr使用group_indices

      library(dplyr)
      df %>% 
         mutate(group_no = group_indices_(., .dots="from"))
      #     from dest group_no
      #1    a    b        1
      #2    a    c        1
      #3    b    d        2
      

      使用data.table 的类似选项是

      library(data.table)
      setDT(df)[, group_no := .GRP, by = from]
      

      【讨论】:

        猜你喜欢
        • 2015-01-03
        • 2014-07-09
        • 2016-03-06
        • 2017-08-16
        • 2016-02-19
        • 1970-01-01
        • 2017-11-30
        • 2019-10-02
        • 2016-09-17
        相关资源
        最近更新 更多