如何用R语言生成小数据集的所有可能组合?含sample函数及替代方案
Hey there! Let's figure out how to generate every possible with-replacement sample from the dataset {2,4,6} using R. Since we want all possible combinations (not just random samples), this boils down to calculating the Cartesian product of the vector with itself three times—each position in the sample can take any of the three values, so we end up with 3³=27 total results.
方法1:无需sample函数的直接方案(推荐)
The simplest and most straightforward way is to use R's built-in expand.grid function, which is designed specifically to generate Cartesian products. Here's how to do it:
# 定义原数据集 x <- c(2, 4, 6) # 通过笛卡尔积生成所有有放回组合 all_combinations <- expand.grid(rep(list(x), 3)) # 转换为每行一个样本的矩阵格式(可选,更易阅读) combinations_matrix <- as.matrix(all_combinations) colnames(combinations_matrix) <- NULL # 输出全部结果 print(combinations_matrix)
这段代码会输出27行数据,每行对应一个唯一的有放回抽样结果。rep(list(x), 3)的作用是告诉expand.grid我们要将向量x与自身做3次笛卡尔积运算。
如果你更倾向于每个样本以列表元素的形式存在,可以这样拆分矩阵:
combinations_list <- split(combinations_matrix, seq(nrow(combinations_matrix)))
方法2:结合sample函数实现
如果一定要用到sample函数(尽管它的设计初衷是随机抽样),我们可以通过枚举索引组合的方式,搭配sample生成所有可能的结果:
x <- c(2, 4, 6) # 先生成所有可能的索引组合(每个位置取1、2、3,对应原向量的三个元素) index_combinations <- expand.grid(rep(list(1:3), 3)) # 遍历每个索引组合,用sample提取对应值 all_samples <- lapply(1:nrow(index_combinations), function(i) { indices <- as.numeric(index_combinations[i, ]) # 这里设置replace=TRUE符合有放回抽样的逻辑,不过我们是按指定索引取值 sample(x, size = 3, replace = TRUE)[indices] }) # 将列表转换为矩阵方便查看 all_samples_matrix <- do.call(rbind, all_samples) print(all_samples_matrix)
需要说明的是,这种方法有点绕——sample本身是用来随机选值的,所以第一种方案在枚举所有组合时效率更高、逻辑更直接。
额外技巧:嵌套使用outer函数
还有一种巧妙的方式可以生成笛卡尔积,就是嵌套调用outer函数:
x <- c(2,4,6) # 先生成拼接后的字符串 all_combinations_str <- outer(outer(x, x), x, FUN = function(a, b) paste(a, b, sep = ",")) # 拆分字符串并转换为数值矩阵 all_combinations_matrix <- matrix( as.numeric(unlist(strsplit(all_combinations_str, ","))), ncol = 3, byrow = TRUE ) print(all_combinations_matrix)
内容的提问来源于stack exchange,提问作者tcollar

