如何从group_by按组编号标记数据表?

我有一个tbl_df在哪里我想group_by(u,v)每个不同的整数组合观察(u,v)。


编辑:这是通过在dplyr 0.4.0中添加group_indices()来解决的


a)然后我想要为每个不同的组分配一些任意的不同数字标签= 1,2,3 …例如组合(u,v)==(2,3)可以得到标签1,(1,3)可以得到2,等等。 如何用一个mutate()做到这一点,没有三步总结和自我连接?

dplyr有一个简洁的函数n() ,但是它给出了组的元素数量,而不是组的总数量 。 在data.table这将被简单地称为.GRP

b)其实我真的想要分配一个string/字符标签('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 uv 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 

更新了答案

 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()) 

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

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

使用iterators

 library(iterators) counter = icount() df %>% group_by(u,v) %>% mutate(label = nextElem(counter)) 

dplyr有一个group_indices()函数,你可以这样使用:

 df %>% mutate(label = group_indices_(df, .dots=c("u", "v"))) %>% group_by(label) ... 

另一种使用data.table方法是

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

这导致:

  uv 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 

用三种不同的方式更新我的答案:

A)使用interaction(u,v)整洁的非dplyr解决scheme:

 > df$label <- factor(interaction(df$u,df$v, drop=T)) [1] 1.3 2.3 2.2 2.4 3.2 2.4 1.2 1.2 2.1 2.1 Levels: 2.1 1.2 2.2 3.2 1.3 2.3 2.4 > match(df$label, levels(df$label)[ rank(unique(df$label)) ] ) [1] 1 2 3 4 5 4 6 6 7 7 

B)使兰迪的整洁快速和脏发生器function答案更紧凑:

 get_next_integer = function(){ i = 0 function(u,v){ i <<- i+1 } } get_integer = get_next_integer() df %>% group_by(u,v) %>% mutate(label = get_integer()) 

C)这里也是一个使用生成器函数滥用全局variables赋值的单线程:

 i <- 0 generate_integer <- function() { return(assign('i', i+1, envir = .GlobalEnv)) } df %>% group_by(u,v) %>% mutate(label = generate_integer()) rm(i)