在 R 中编写组合
writing combinations in R
我有一个这样的数据框 (df)
name col1 col2
pippo A;B;C E;F;G;
pluto G;H X;Y;Z;E;O;D
我想写下 col1 的 1 个元素和 col 2 的 1 个元素之间的所有可能组合,并将每个组合作为数据框返回,例如
name col1 col2
pippo A E
pippo A F
pippo A G
pippo B E
... and so on.
考虑到我有所有字母,并且 col1 和 col2 中的元素数量可以变化(从 1 个元素到 10 个元素),R 可以吗?
按;
拆分列后,我们可以使用crossing
library(dplyr)
library(tidyr)
library(purrr)
df %>%
transmute(name, new = map2(strsplit(col1, ";"),
strsplit(col2, ";"), ~ crossing(col1 = .x, col2 = .y))) %>%
unnest(c(new))
-输出
# A tibble: 21 x 3
# name col1 col2
# <chr> <chr> <chr>
# 1 pippo A E
# 2 pippo A F
# 3 pippo A G
# 4 pippo B E
# 5 pippo B F
# 6 pippo B G
# 7 pippo C E
# 8 pippo C F
# 9 pippo C G
#10 pluto G D
# … with 11 more rows
数据
df <- structure(list(name = c("pippo", "pluto"), col1 = c("A;B;C",
"G;H"), col2 = c("E;F;G;", "X;Y;Z;E;O;D")), class = "data.frame",
row.names = c(NA,
-2L))
Base R。这不像 akrun 的答案那样清晰易读,但它只是 Base R。
eg <- do.call(Map, c(
list(f=function(...) do.call(expand.grid,
lapply(list(...), function(s) strsplit(s, ";")[[1]]))),
dat[,-1]))
cbind.data.frame(name = rep(dat$name, sapply(eg, nrow)), do.call(rbind, eg))
# name col1 col2
# A;B;C.1 pippo A E
# A;B;C.2 pippo B E
# A;B;C.3 pippo C E
# A;B;C.4 pippo A F
# A;B;C.5 pippo B F
# A;B;C.6 pippo C F
# A;B;C.7 pippo A G
# A;B;C.8 pippo B G
# A;B;C.9 pippo C G
# G;H.1 pluto G X
# G;H.2 pluto H X
# G;H.3 pluto G Y
# G;H.4 pluto H Y
# G;H.5 pluto G Z
# G;H.6 pluto H Z
# G;H.7 pluto G E
# G;H.8 pluto H E
# G;H.9 pluto G O
# G;H.10 pluto H O
# G;H.11 pluto G D
# G;H.12 pluto H D
我有一个这样的数据框 (df)
name col1 col2
pippo A;B;C E;F;G;
pluto G;H X;Y;Z;E;O;D
我想写下 col1 的 1 个元素和 col 2 的 1 个元素之间的所有可能组合,并将每个组合作为数据框返回,例如
name col1 col2
pippo A E
pippo A F
pippo A G
pippo B E
... and so on.
考虑到我有所有字母,并且 col1 和 col2 中的元素数量可以变化(从 1 个元素到 10 个元素),R 可以吗?
按;
crossing
library(dplyr)
library(tidyr)
library(purrr)
df %>%
transmute(name, new = map2(strsplit(col1, ";"),
strsplit(col2, ";"), ~ crossing(col1 = .x, col2 = .y))) %>%
unnest(c(new))
-输出
# A tibble: 21 x 3
# name col1 col2
# <chr> <chr> <chr>
# 1 pippo A E
# 2 pippo A F
# 3 pippo A G
# 4 pippo B E
# 5 pippo B F
# 6 pippo B G
# 7 pippo C E
# 8 pippo C F
# 9 pippo C G
#10 pluto G D
# … with 11 more rows
数据
df <- structure(list(name = c("pippo", "pluto"), col1 = c("A;B;C",
"G;H"), col2 = c("E;F;G;", "X;Y;Z;E;O;D")), class = "data.frame",
row.names = c(NA,
-2L))
Base R。这不像 akrun 的答案那样清晰易读,但它只是 Base R。
eg <- do.call(Map, c(
list(f=function(...) do.call(expand.grid,
lapply(list(...), function(s) strsplit(s, ";")[[1]]))),
dat[,-1]))
cbind.data.frame(name = rep(dat$name, sapply(eg, nrow)), do.call(rbind, eg))
# name col1 col2
# A;B;C.1 pippo A E
# A;B;C.2 pippo B E
# A;B;C.3 pippo C E
# A;B;C.4 pippo A F
# A;B;C.5 pippo B F
# A;B;C.6 pippo C F
# A;B;C.7 pippo A G
# A;B;C.8 pippo B G
# A;B;C.9 pippo C G
# G;H.1 pluto G X
# G;H.2 pluto H X
# G;H.3 pluto G Y
# G;H.4 pluto H Y
# G;H.5 pluto G Z
# G;H.6 pluto H Z
# G;H.7 pluto G E
# G;H.8 pluto H E
# G;H.9 pluto G O
# G;H.10 pluto H O
# G;H.11 pluto G D
# G;H.12 pluto H D