R- 查找值的唯一排列
R- Find Unique Permutations of Values
我希望创建包含两个不同值的向量的所有可能排列,其中我控制每个值的比例。
例如,如果我有一个长度为 3 的向量,并且我希望所有可能的组合都包含一个 1,那么我想要的输出是一个如下所示的列表:
list.1 <- list(c(1,0,0), c(0,1,0), c(0,0,1))
相比之下,如果我想要包含三个 1 的所有可能组合,我想要的输出是一个如下所示的列表:
list.3 <- list(c(1,1,1))
换句话说,1
和 0
值的模式很重要,但所有 1
都应被视为与所有其他 1
相同s.
根据在这里和其他地方的搜索,我尝试了几种方法:
expand.grid(0:1, 0:1, 0:1) # this includes all possible combinations of 1, 2, or 3 ones
permn(c(0,1,1)) # this does not treat the ones as identical (e.g. it produces (0,1,1) twice)
unique(permn(c(0,1,1))) # this does the job!
因此,使用包 combinat
中的函数 permn
似乎很有希望。然而,当我将其放大到我的实际问题时(一个长度为 20 的向量,有 50% 1 和 50% 0,我 运行 遇到了问题:
unique(permn(c(rep(1,10), rep(0, 10))))
# returns the error:
Error in vector("list", gamma(n + 1)) :
vector size specified is too large
我的理解是,发生这种情况是因为在调用 permn
时,它生成了一个包含所有可能排列的列表,即使其中许多排列是相同的,而且这个列表对于 R 来说太大了手柄。
有人对如何解决这个问题有建议吗?
抱歉,如果之前已经回答过这个问题 - 有很多很多包含类似语言但不同问题的 SO 问题,我无法找到满足我需要的解决方案!
问题确实是您最初计算的是所有阶乘 (20) (~10^18) 排列,这不适合您的记忆。
您正在寻找的是一种计算多重排列的有效方法。 multicool
包可以做到这一点:
library(multicool)
res <- allPerm(initMC(c(rep(0,10),rep(1,10) )))
这个计算在我的笔记本电脑上大约需要两分钟,但绝对可行。
expand.grid
包括所有排列,这不应该是一个破坏因素。只需在:
之后添加一个子集
combinations <- function(size, choose) {
d <- do.call("expand.grid", rep(list(0:1), size))
d[rowSums(d) == choose,]
}
combinations(size=10, choose=3)
# Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10
# 8 1 1 1 0 0 0 0 0 0 0
# 12 1 1 0 1 0 0 0 0 0 0
# 14 1 0 1 1 0 0 0 0 0 0
# 15 0 1 1 1 0 0 0 0 0 0
# 20 1 1 0 0 1 0 0 0 0 0
# 22 1 0 1 0 1 0 0 0 0 0
...
我希望创建包含两个不同值的向量的所有可能排列,其中我控制每个值的比例。
例如,如果我有一个长度为 3 的向量,并且我希望所有可能的组合都包含一个 1,那么我想要的输出是一个如下所示的列表:
list.1 <- list(c(1,0,0), c(0,1,0), c(0,0,1))
相比之下,如果我想要包含三个 1 的所有可能组合,我想要的输出是一个如下所示的列表:
list.3 <- list(c(1,1,1))
换句话说,1
和 0
值的模式很重要,但所有 1
都应被视为与所有其他 1
相同s.
根据在这里和其他地方的搜索,我尝试了几种方法:
expand.grid(0:1, 0:1, 0:1) # this includes all possible combinations of 1, 2, or 3 ones
permn(c(0,1,1)) # this does not treat the ones as identical (e.g. it produces (0,1,1) twice)
unique(permn(c(0,1,1))) # this does the job!
因此,使用包 combinat
中的函数 permn
似乎很有希望。然而,当我将其放大到我的实际问题时(一个长度为 20 的向量,有 50% 1 和 50% 0,我 运行 遇到了问题:
unique(permn(c(rep(1,10), rep(0, 10))))
# returns the error:
Error in vector("list", gamma(n + 1)) :
vector size specified is too large
我的理解是,发生这种情况是因为在调用 permn
时,它生成了一个包含所有可能排列的列表,即使其中许多排列是相同的,而且这个列表对于 R 来说太大了手柄。
有人对如何解决这个问题有建议吗?
抱歉,如果之前已经回答过这个问题 - 有很多很多包含类似语言但不同问题的 SO 问题,我无法找到满足我需要的解决方案!
问题确实是您最初计算的是所有阶乘 (20) (~10^18) 排列,这不适合您的记忆。
您正在寻找的是一种计算多重排列的有效方法。 multicool
包可以做到这一点:
library(multicool)
res <- allPerm(initMC(c(rep(0,10),rep(1,10) )))
这个计算在我的笔记本电脑上大约需要两分钟,但绝对可行。
expand.grid
包括所有排列,这不应该是一个破坏因素。只需在:
combinations <- function(size, choose) {
d <- do.call("expand.grid", rep(list(0:1), size))
d[rowSums(d) == choose,]
}
combinations(size=10, choose=3)
# Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10
# 8 1 1 1 0 0 0 0 0 0 0
# 12 1 1 0 1 0 0 0 0 0 0
# 14 1 0 1 1 0 0 0 0 0 0
# 15 0 1 1 1 0 0 0 0 0 0
# 20 1 1 0 0 1 0 0 0 0 0
# 22 1 0 1 0 1 0 0 0 0 0
...