在 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)
.
我正在模拟泊松分布(参数为 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)
.