如何通过group_by中的group-number对数据表进行编号/标记?

smc*_*mci 17 group-by r indices dplyr

我有一个tbl_df我想要group_by(u, v)观察的每个不同的整数组合(u, v).


编辑:通过添加group_indices()dplyr 0.4.0解决了这个问题


a)然后我想为每个不同的组分配一些任意的不同数字标签= 1,2,3 ......例如组合(u,v)==(2,3)可以得到标签1,(1,3)可以得到2,依此类推.如何使用一个mutate(),没有三步总结和自我加入?

dplyr有一个整洁的功能n(),但是,让元素的数目之内它的组,而不是整体的组的数目.data.table这将简单地被称为.GRP.

b)实际上我真正想要分配字符串/字符标签('A','B',...).但是按整数编号组是很好的,因为我可以使用integer_to_label(i)如下.除非有一个聪明的方法来合并这两个?但不要冒这个角色.

set.seed(1234)

# Helper fn for mapping integer 1..26 to character label
integer_to_label <- function(i) { substr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",i,i) }

df <- tbl_df(data.frame(u=sample.int(3,10,replace=T), v=sample.int(4,10,replace=T)))

# Want to label/number each distinct group of unique (u,v) combinations
df %>% group_by(u,v) %>% mutate(label = n()) # WRONG: n() is number of element within its group, not overall number of group

   u v
1  2 3
2  1 3
3  1 2
4  2 3
5  1 2
6  3 3
7  1 3
8  1 2
9  3 1
10 3 4

KLUDGE 1: could do df %>% group_by(u,v) %>% summarize(label = n()) , then self-join
Run Code Online (Sandbox Code Playgroud)

Cal*_*imo 42

dplyr有一个group_indices()你可以使用的功能:

df %>% 
    mutate(label = group_indices(., u, v)) %>% 
    group_by(label) ...
Run Code Online (Sandbox Code Playgroud)

  • group_indices() 使用分组变量的(字母顺序)顺序,有什么方法可以使用它来保留表中的顺序,或者应用您自己的顺序? (5认同)

Ren*_*rop 11

使用的另一种方法data.table

require(data.table)
setDT(df)[,label:=.GRP, by = c("u", "v")]
Run Code Online (Sandbox Code Playgroud)

这导致:

    u v label
 1: 2 1     1
 2: 1 3     2
 3: 2 1     1
 4: 3 4     3
 5: 3 1     4
 6: 1 1     5
 7: 3 2     6
 8: 2 3     7
 9: 3 2     6
10: 3 4     3
Run Code Online (Sandbox Code Playgroud)


Sam*_*rke 9

从 dplyr 版本 1.0.4 开始,该函数cur_group_id()已取代旧函数group_indices

在分组的 data.frame 上调用它:

df %>%
  group_by(u, v) %>%
  mutate(label = cur_group_id())

# A tibble: 10 x 3
# Groups:   u, v [6]
       u     v label
   <int> <int> <int>
 1     2     2     4
 2     2     2     4
 3     1     3     2
 4     3     2     6
 5     1     4     3
 6     1     2     1
 7     2     2     4
 8     2     4     5
 9     3     2     6
10     2     4     5
Run Code Online (Sandbox Code Playgroud)


Ran*_*Lai 7

更新答案

get_group_number = function(){
    i = 0
    function(){
        i <<- i+1
        i
    }
}
group_number = get_group_number()
df %>% group_by(u,v) %>% mutate(label = group_number())
Run Code Online (Sandbox Code Playgroud)

您还可以考虑以下稍微不可读的版本

group_number = (function(){i = 0; function() i <<- i+1 })()
df %>% group_by(u,v) %>% mutate(label = group_number())
Run Code Online (Sandbox Code Playgroud)

使用iterators

library(iterators)

counter = icount()
df %>% group_by(u,v) %>% mutate(label = nextElem(counter))
Run Code Online (Sandbox Code Playgroud)

  • 你让我想起了 `iterators` 包。我以前从未使用过它。(并查看更新的解决方案)。但本质上和我原来的方法是等价的。 (2认同)