这是我的矢量:
vec <- c("A", "B", "C")
Run Code Online (Sandbox Code Playgroud)
而且,我希望获得vec的所有7种组合.
desired_output <- tibble( ~A, ~B, ~C,
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 0,
1, 0, 1,
0, 1, 1,
1, 1, 1)
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法:
#install.packages("gtools")
library(gtools)
r <- c(1,2, 3)
df1 <- purrr::map(r, ~combinations(3,.x,vec))
df2 <- per %>% map_dfr(~data.frame(.x))
Run Code Online (Sandbox Code Playgroud)
但无法获得理想的结果.你能建议一个解决方案,特别是在vec中有不同数量的元素吗?
基础解决方案
vec = c("A", "B", "C")
inp = rep(list(0:1), length(vec))
names(inp) = vec
do.call(expand.grid, inp)
# A B C
# 1 0 0 0
# 2 1 0 0
# 3 0 1 0
# 4 1 1 0
# 5 0 0 1
# 6 1 0 1
# 7 0 1 1
# 8 1 1 1
Run Code Online (Sandbox Code Playgroud)
这给出了所有8种组合,如果你想要排除全0情况我建议事后做.
感谢Henrik的评论,这是一个purrr版本:
vec = c("A", "B", "C")
library(purrr)
pur = rerun(length(vec), 0:1)
names(pur) = vec
cross_df(pur)
# # A tibble: 8 x 3
# A B C
# <int> <int> <int>
# 1 0 0 0
# 2 1 0 0
# 3 0 1 0
# 4 1 1 0
# 5 0 0 1
# 6 1 0 1
# 7 0 1 1
# 8 1 1 1
Run Code Online (Sandbox Code Playgroud)
对时间感到好奇吗?在这个小例子中,base解决方案的速度提高了大约6倍,尽管两者都足够快,但这并不重要.在较长的输入上,这个比例似乎保持不变,我的速度提高了大约6倍vec = LETTERS[1:10].试过LETTERS[1:20]但厌倦了等待,所以我流产了.
vec = LETTERS[1:10]
microbenchmark(
base = {
inp = rep(list(0:1), length(vec));
names(inp) = vec;
do.call(expand.grid, inp);},
purrr = {
pur = rerun(length(vec), 0:1);
names(pur) = vec;
cross_df(pur);
},
times = 10L
)
# Unit: microseconds
# expr min lq mean median uq max neval
# base 789.668 868.152 1023.248 967.4635 1096.962 1388.559 10
# purrr 45617.167 45960.080 59621.746 54181.5545 78944.986 87511.789 10
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |