我是r的新手。我需要用置换填充数据集。我为小型数据集创建了一个,其中有4列(插槽),可以用0到8之间的任何数字填充。它们的总和应等于6。
我需要对较大的集合进行处理,其中column(slots = 6)和sequence为1到200,所需的总和为100。根据上述脚本,这花费了太多时间。请提出另一种方法。
谢谢。
library(gtools)
library(dplyr)
df <- as.data.frame( permutations(5,4,seq(0,8,1))) %>%
mutate(sum = `V1`+`V2`+`V3`+`V4`) %>%
filter(sum == 6) %>%
select(-sum)
答案 0 :(得分:1)
一个选项是:
as.data.frame(permutations(5, 4, seq(0, 8, 1))) %>%
filter(reduce(., `+`) == 6)
另一方面,这也可以在dplyr
或其他包之外进行,例如:
df <- as.data.frame(permutations(5, 4, seq(0, 8, 1)))
df[reduce(df, `+`) == 6,]
您也可以尝试data.table
,例如:
library(data.table)
dt <- setDT(as.data.frame(permutations(5, 4, seq(0, 8, 1))))
dt[Reduce(`+`, mget(names(dt))) == 6]
或者也可以是另一种选择-可能更慢-(在如上所述保存到dt
之后):
dt[dt[, rowSums(.SD) == 6]]
答案 1 :(得分:1)
使用RcppAlgos
(我是作者),这很简单。
RcppAlgos::permuteGeneral(seq(0, 8, 1), 4,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 6)
下面的算法经过优化,可以快速删除不可能的解决方案。我们也只考虑检查组合,因为加法/乘法是可交换的,顺序无关紧要。一旦找到合适的组合,我们就会生成该特定组合的所有排列。这也有助于我们将Rcpp
用于提高效率。
对于具有200个数字和6列的OP的现实世界问题,可行性将在很大程度上取决于所需的总和。如果我们考虑了平均总和(将最多),则可能需要考虑其他方法,因为可能的解决方案的剪切数超过了2^31 - 1
。这也将花费大量时间。仅用5列和500的总和,我什至无法产生排列。但是,我可以产生组合:
res <- RcppAlgos::comboGeneral(1:200, 5,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 500,
upper = 1e8) ## upper argument constrains the output to a maximum number of results
nrow(res)
[1] 7669861
鉴于没有重复,我们可以计算出排列的数量:
7669861 *阶乘(5)= 920,383,320
这是我得到的错误:
res <- RcppAlgos::permuteGeneral(1:200, 5,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 500,
upper = 921000000)
Show Traceback
Rerun with Debug
Error: vector memory exhausted (limit reached?)
如果所需的总和与平均总和相比相对较小或较大,则可以进行计算。例如,如果期望的总和为100,我们可以快速获得所有排列:
system.time(res <- RcppAlgos::permuteGeneral(1:200, 6,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 100,
upper = 1e8))
user system elapsed
2.213 0.525 2.753
nrow(res)
[1] 47395440