对于group_by(u, v)
观察到的每个不同的整数组合,我有一个tbl_df,我希望(u, v)
。
编辑:通过在dplyr 0.4.0
中添加group_indices()
来解决此问题
a)然后我想为每个不同的组分配一些任意的不同数字标签= 1,2,3 ......
例如组合(u,v)==(2,3)可以得到标签1,(1,3)可以得到2,依此类推。
如何使用一个mutate()
进行此操作,而不进行三步汇总和自我加入?
dplyr有一个整洁的函数n()
,但是它给出了元素元素的数量,而不是的整体数量。 In data.table
this would simply be called .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
答案 0 :(得分:38)
dplyr有一个group_indices()
函数,您可以这样使用:
df %>%
mutate(label = group_indices(., u, v)) %>%
group_by(label) ...
答案 1 :(得分:8)
使用data.table
的另一种方法是
require(data.table)
setDT(df)[,label:=.GRP, by = c("u", "v")]
导致:
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
答案 2 :(得分:4)
更新回答
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))
答案 3 :(得分:2)
以三种不同的方式更新我的答案:
A)使用interaction(u,v)
:
> 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)让Randy的快速和肮脏的发电机功能更加紧凑:
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)这里还有一个使用生成器函数的单行程序,滥用this的全局变量赋值:
i <- 0
generate_integer <- function() { return(assign('i', i+1, envir = .GlobalEnv)) }
df %>% group_by(u,v) %>% mutate(label = generate_integer())
rm(i)
答案 4 :(得分:2)
从 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