我正在寻找最有效的方法来创建基于R中n个不同系列的组合.

Base R有一个名为expand.grid的很好的函数,它将所有组合作为一个数据框返回,但我需要将每个组合作为向量作为单独的列表元素.

因此,从那时起,实现我想要的东西应该不是一项困难的任务,但我首先需要创建一个数据框这一事实似乎是这个过程中不必要的一步.

举个例子:让我们假设我想要所有的组合,其中第一个元素是1,2,3或4,第二个是1或2,第三个是1,2或3.输入应该是序列中的最大整数:

library(dplyr)
c(4,2,3) %>% #This is the input; the length can be anything, here it happens to be 3
    lapply(\(elem) seq(elem)) %>% #Here we create the sequences: 1,2,3,4 & 1,2 & 1,2,3
    expand.grid %>% #A data frame with all the possible combinations
    {split(unlist(.),seq(nrow(.)))} #We unlist the whole data frame into one vector, and split it into 1,2,...,nrow(data frame) equally sized vectors, which ultimately become list elements

那么,有没有更有效的方法来实现这一点呢?

推荐答案

(我添加这一点只是为了删除反对票,Aku-Ville Lehtimäki)

如果想要提高效率,可以考虑用C++编写代码:

Rcpp::cppFunction("
std::vector<std::vector<int>> product(std::vector<int> x){
  std::vector<std::vector<int>> result = {{}};
  for (auto i: x){
      std::vector<std::vector<int>> sub_result;
      for (auto j: result) for (auto k = 1; k<=i;k++) {
          std::vector<int> row(j);
          row.push_back(k);
          sub_result.push_back(row);
      }
      result = sub_result;
  }
  return result;
}
")

product(1:3)
[[1]]
[1] 1 1 1

[[2]]
[1] 1 1 2

[[3]]
[1] 1 1 3

[[4]]
[1] 1 2 1

[[5]]
[1] 1 2 2

[[6]]
[1] 1 2 3

编辑

我相信它可能只使用索引,而不是数据复制,这将显着提高速度. 下面是实现一半索引的方法:

Rcpp::cppFunction("
std::vector<std::vector<int>> product_2(std::vector<int> x){
  std::vector<std::vector<int>> result = {{}};
  for (auto i: x){
      std::vector<std::vector<int>> sub_result;
      for (auto j: result) {
        int n = j.size();
        j.resize(n+1);
        for (auto k = 1; k<=i;k++) {
          j[n] = k;
          sub_result.push_back(j);
        }
      }
      result = sub_result;
  }
  return result;
}
")

microbenchmark::microbenchmark(product(n), product_2(n), check = 'equal')
Unit: milliseconds
         expr    min      lq     mean  median      uq     max neval
   product(n) 5.3796 5.53625 6.997803 6.17555 7.87635 14.4701   100
 product_2(n) 3.3674 3.55285 4.583415 4.14890 5.50670  8.4493   100

请注意,这不是最好的,但这是迄今为止我能想到的最好的

R相关问答推荐

使用ggcorrplot在相关性矩阵上标注supertitle和index标签

无法在我的情节中表现出显着的差异

对lme 4对象运行summary()时出错(diag中的错误(from,names = RST):对象unpackedMatrix_diag_get找不到)

从有序数据中随机抽样

在发布到PowerBI Service时,是否可以使用R脚本作为PowerBI的数据源?

r—绘制相交曲线

derrr mutate case_when grepl不能在R中正确返回值

当月份额减go 当月份额

如何根据嵌套元素的名称高效而优雅地确定它属于哪个列表?

非线性混合效应模型(NLME)预测变量的置信区间

使用R中的正则表达式将一列分割为多列

当我添加美学时,geom_point未对齐

将箭头绘制在图形外部,而不是图形内部

将文本批注减少到gglot的y轴上的单个值

对R中的列表列执行ROW Mean操作

用满足特定列匹配的另一行替换NA行

R-找出存在其他变量的各种大小的所有组合

我已经运行了几个月的代码的`Palette()`中出现了新的gglot错误

通过比较来自多个数据框的值和R中的条件来添加新列

如何使用包含要子集的值的列表或数据框来子集多个列?