在 R 中循环以提取列表列表

Loop in R to extract list of lists

我正在模拟泊松分布(参数为 9)的事件数。对于每个事件,我使用参数为 2 和 1.1

的对数正态分布来模拟事件的价格

我是运行100次模拟(每次模拟代表一年)。代码(我很满意)是:

simul <- list()
for(i in 1:100) {simul[[i]] <- rlnorm (rpois(1, 9), meanlog = 2, sdlog = 1.1) }

我的问题是输出 "simul" 是一个列表列表,我不知道如何对其应用基本操作。

我希望能够: 1. 限制每个单独的模拟值(由于预算限制) 2. 分别获得每年所有模拟值的总和(有上限和无上限) 3. 获得每一年的平均值(有和没有上限) 4. 计算每年的第 95 个百分位数(有和没有上限) 5. 将结果输出到数据框中(这样一列代表总数,一列代表平均值,一列代表百分位数等),每一行代表一年

似乎有用的是我拉出个人列表:

sim1 <- simul[1]

我现在可以使用 "unlist" 来展平列表并应用我想要的任何操作。

sims1 <- data.frame(unlist(sim1), nrow=length(sim1), byrow=F)
sims1 <- subset(sims1, select = c(unlist.sim1.))
colnames(sims1) <- "sim1"

quantile <- data.frame(quantile(sims1$sim1, probs = c(0.95)))

但我不想为列表中的每个子列表编写 100 次上述逻辑...有没有办法解决它?

如有任何帮助,我们将不胜感激。

你实际上没有一个列表列表,你有一个向量列表。对于列表,单个括号子集将 return 一个列表,例如simul[1:3] 将 return 是 simul 的前 3 项的列表,为了保持一致性 simul[1] return 是 simul 的第一项的列表.

要提取元素而不是长度为 1 的列表,请使用 [[simul[[1]] 是您不需要 运行 unlist() 的向量。

列表的好处是您可以使用 for 循环或 lapply/sapply 函数来处理它们。例如

raw_means = sapply(simul, mean)
raw_sums = sapply(simul, sum)
raw_95 = sapply(simul, quantile, probs = 0.95)
result = data.frame(raw_means, raw_sums, raw_95)

或者循环,

raw_means = raw_sums = raw_95 = numeric(length(simul))
for (i in seq_along(simul)) {
  raw_means[i] = mean(simul[[i]])
  raw_sums[i] = sum(simul[[i]])
  raw_95[i] = quantile(simul[[i]], probs = 0.95)
}
result = data.frame(raw_means, raw_sums, raw_95)

当你说 "cap" 时,我不确定你是指子集还是减少值(例如,使用 pmin),所以我会把它留给你。但我建议制作一个新列表,例如 simul_cap = lapply(simul, pmin, 9)(如果这是您想要的操作)和 运行 在您的上限列表中使用相同的代码。您甚至可以将汇总统计信息作为一个函数,这样您就不会复制粘贴一堆,而是最终执行 raw_result = foo(simul)cap_result = foo(simul_cap).