递归列表的组合

时间:2013-02-26 00:58:50

标签: r

假设我有三个字:"blue""red""pink"

我希望生成所有字母组合,其中我从"蓝色"中取出两个字母,然后从" red"中添加两个字母,然后再添加两个字母"粉红色",例如

blrdpk

uerdin

等...

在R中,我通过使用

将每个单词的字符分配到列表元素中来编码我的三个单词
words <- list( list("b","l","u","e"),  list("r","e","d"),  list("p","i","n","k") )

我知道我可以lapply使用combn(words[[i]],m=2)来获取每个单词的2个字母的所有组合。

我有两个问题:

  1. 是否有更高级的combn()版本,允许您选择和连接来自不同桶的组合&#39;使用递归列表?

  2. 如果没有高级版本的combn(),那么从三个单词中的每个单词连接每个单独的2个字母组合的最佳方法是什么?

  3. 如果我想从每个单词中输入不同数量的字母,是否有一种简单的方法可以做到这一点? [在其中一个答案中添加了用户评论]

2 个答案:

答案 0 :(得分:4)

可能有更高级版本的combn,但它已经非常先进了。例如,您可以通过指定FUN参数将函数应用于每个组合。将它与expand.grid和Reduce相结合,你就会得到像

这样的东西
Reduce(paste0, expand.grid(lapply(words, function(x) {
  combn(x, m=2, FUN=paste0, collapse="")
})))

修改 如果要从每个单词中选择的字母数量不同,则可以将此数字添加为单词列表的每个元素的属性,然后将该属性用作m的{​​{1}}参数。例如,为第一个单词选择一个字母,为第二个单词选择两个字母,为第三个单词选择三个字母:

combn

或者你可以像geektrader的回答一样使用mapply。

答案 1 :(得分:2)

以下是从单词列表和从每个单词中挑选的字符数列表到期望结果的解决方案

> words
[1] "blue" "red"  "pink"
> wordsplit <- strsplit(words, split="")
> wordsplit
[[1]]
[1] "b" "l" "u" "e"

[[2]]
[1] "r" "e" "d"

[[3]]
[1] "p" "i" "n" "k"

> lengths <- c(2, 1, 3)
> combos <- expand.grid(mapply(function(word, n) combn(word,m=n, FUN=paste0, collapse=""), wordsplit, lengths))
> head(combos)
  Var1 Var2 Var3
1   bl    r  pin
2   bu    r  pin
3   be    r  pin
4   lu    r  pin
5   le    r  pin
6   ue    r  pin

> do.call('paste0', combos)
 [1] "blrpin" "burpin" "berpin" "lurpin" "lerpin" "uerpin" "blepin" "buepin" "beepin" "luepin" "leepin" "ueepin" "bldpin" "budpin" "bedpin" "ludpin"
[17] "ledpin" "uedpin" "blrpik" "burpik" "berpik" "lurpik" "lerpik" "uerpik" "blepik" "buepik" "beepik" "luepik" "leepik" "ueepik" "bldpik" "budpik"
[33] "bedpik" "ludpik" "ledpik" "uedpik" "blrpnk" "burpnk" "berpnk" "lurpnk" "lerpnk" "uerpnk" "blepnk" "buepnk" "beepnk" "luepnk" "leepnk" "ueepnk"
[49] "bldpnk" "budpnk" "bedpnk" "ludpnk" "ledpnk" "uedpnk" "blrink" "burink" "berink" "lurink" "lerink" "uerink" "bleink" "bueink" "beeink" "lueink"
[65] "leeink" "ueeink" "bldink" "budink" "bedink" "ludink" "ledink" "uedink"