HOWTO · R
R 中的 replicate()函数
本教程介绍了 R 中 replicate()函数的使用。
本页内容
R 的 replicate() 会重复计算一个表达式,并收集每次计算的结果。当需要多次执行同一计算、随机抽样或模拟时,它很有用。结果的形状取决于表达式的返回值以及 simplify 参数:收集的值可以组成向量、矩阵、数组或列表。
replicate() 重复计算什么
第一个参数 n 指定计算次数。第二个参数 expr 会在每次重复时计算一次。例如,下面的代码会返回五个标量值 1:
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
result <- replicate(5, 1)
print(result)
返回的向量中,每次计算对应一个值。如果 expr 使用了随机性,每次计算都可能得到不同的值;replicate() 会收集这些结果,但不会让它们变成相同的值。
语法与 simplify 参数
基本形式为 replicate(n, expr, simplify = "array")。其中,n 是重复次数,expr 是要计算的表达式,而 simplify 用于控制 R 如何简化收集到的结果。默认值 "array" 会根据结果形状进行简化:标量结果可以组成向量,长度相同的向量可以组成矩阵,更高维的结果则可以组成数组。若要保留列表,例如让每次重复返回的结果仍是独立对象,请使用 simplify = FALSE。
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
values <- replicate(3, c("red", "blue"), simplify = FALSE)
print(typeof(values))
print(length(values))
[1] "list"
[1] 3
typeof() 会报告底层类型,length() 会计算列表元素的数量。
重复标量或向量
标量表达式每次重复会产生一个结果。如果表达式每次都返回长度相同的向量,replicate() 会把每个向量放在矩阵的一列中。因此,矩阵的行对应向量中的位置,列对应重复次数。
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
result <- replicate(3, seq(1, 4))
print(result)
如果计算会返回固定长度的向量,也可以使用相同的模式。如果结果长度不固定,就无法将这些值排列成规则矩阵;此时可设置 simplify = FALSE,将每个结果保留在列表的一个元素中。
在 for() 循环中使用 replicate()
for() 循环可以构建一个值,并让这个值成为每次重复的结果。在表达式中初始化并填充一个向量,然后让该向量成为表达式的最后一个值:
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
result <- replicate(2, {
values <- numeric(4)
for (i in seq_len(4)) {
values[i] <- i * 2
}
values
})
print(result)
最后一个表达式是 values,因此每次计算都会返回已填好的向量,简化后的结果中每次重复对应一列。for() 循环本身会返回 NULL;在循环中打印值,并不会让这些打印出的值成为循环的返回值。如果重复计算的表达式只有这样的循环,每次重复都会返回 NULL。若要在结果中取得这些值,请先将它们存储起来,并返回存储结果的对象。
重复随机模拟
随机表达式会在每次重复时重新计算。例如,rnorm(4) 会从标准正态分布中抽取四个值。结果矩阵的每一列包含一次抽取的四个值;抽样数值会随运行而变化,因此不应将它们视为固定输出。
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
set.seed(42)
draws <- replicate(3, rnorm(4))
print(dim(draws))
也可以重复执行模拟函数。先定义一个函数,让它返回所需的统计量或测量值,再将该函数调用作为 expr 传入。例如,一个通过 runif(1) 抽取单个值的函数可以执行多次,以研究这些模拟值的分布。若需要可复现的随机序列,请选择并记录随机种子;若不固定种子,不同运行得到的值通常会有所不同。
使用 replicate() 进行自助重抽样
自助重抽样通过从观测数据中有放回地抽取样本来估计不确定性。每次重复时,sample() 都会创建一个重抽样数据集。如果每个样本的大小都与原始数据集相同,简化后的结果就是一个矩阵,其中每列代表一次自助重抽样。
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
original_data <- c(2, 4, 6, 8, 10)
set.seed(42)
resamples <- replicate(5, sample(original_data, replace = TRUE))
print(dim(resamples))
每一列代表一个重抽样数据集;由于抽样是有放回的,同一个值可能出现多次。如果要对统计量进行自助重抽样,而不是保留每个抽样值,可以在重复表达式中计算统计量,例如 mean(sample(original_data, replace = TRUE))。这样每次重复会产生一个统计量,通常收集为一个向量。