【发布时间】:2019-12-15 09:37:51
【问题描述】:
这里有一个问题:我有来自一组 N 个元素的 M 个元素的所有可能组合(N 选择 M)。每个组合都有一个分配的值。
N = 5 和 M = 3 的示例:
library(tidyverse)
df <- letters[1:5] %>% combn( m = 3 ) %>% t() %>%
as_tibble( .name_repair = function(x) {paste0('id', 1:length(x))} )
df$val <- runif( nrow(df) )
这给出了一组 10 种组合:
# A tibble: 10 x 4
id1 id2 id3 val
<chr> <chr> <chr> <dbl>
1 a b c 0.713
2 a b d 0.314
3 a b e 0.831
4 a c d 0.555
5 a c e 0.915
6 a d e 0.954
7 b c d 0.131
8 b c e 0.0583
9 b d e 0.533
10 c d e 0.857
现在我想添加组合,使得结果表示选择 M 个元素而不替换 (N!/(NM)!),但保留每个 M 个元素集合的值。
因此,继续使用示例,结果应该包含 543=60 行。例如,我可以在列的“手动”排列中做到这一点:
# add missing combinations
df_perm <- df %>% bind_rows(
# 1, 3, 2
df %>% mutate( tmp = id2, id2 = id3, id3 = tmp ) %>%
select( -tmp )
) %>% bind_rows(
# 2, 1, 3
df %>% mutate( tmp = id1, id1 = id2, id2 = tmp ) %>%
select( -tmp )
) %>% bind_rows(
# 2, 3, 1
df %>% mutate( tmp = id1, id1 = id2, id2 = id3, id3 = tmp ) %>%
select( -tmp )
) %>% bind_rows(
# 3, 1, 2
df %>% mutate( tmp = id2, id2 = id1, id1 = id3, id3 = tmp ) %>%
select( -tmp )
) %>% bind_rows(
# 3, 2, 1
df %>% mutate( tmp = id3, id3 = id1, id1 = tmp ) %>%
select( -tmp )
)
但是,对于 M>3,这很快变得不可行。
实现相同结果的更优雅的方法是什么?
【问题讨论】:
-
最好设置种子,以便轻松验证结果。
-
感谢@JosephWood 的指点,下次我会记住的。
标签: r dplyr combinations permutation tidyverse