L oop в R, чтобы извлечь список списков - PullRequest
0 голосов
/ 23 марта 2020

Я моделирую количество событий из распределения Пуассона (с параметром 9). Для каждого события я моделирую цену события, используя логнормальное распределение с параметрами 2 и 1.1

Я выполняю 100 симуляций (каждая симуляция представляет год). Код (которым я доволен):

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

Моя проблема в том, что вывод "simul" представляет собой список списков, и я не знаю, как применить к нему операции basi c ,

Я хочу иметь возможность: 1. ограничить каждое отдельное смоделированное значение (из-за бюджетных ограничений) 2. получить сумму всех смоделированных значений отдельно для каждого года (с ограничением и без него) 3. получить среднее значение для каждого отдельного года (с ограничением и без него) 4. рассчитать 95-й процентиль для каждого года (с ограничением и без) 5. вывести результаты в информационный кадр (так, чтобы один столбец представлял общее, один средний, один процентиль et c) и каждая строка представляет год

Что-то, что работает, это то, что я вытаскиваю отдельные списки:

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)))

Но я не хочу записывать вышеуказанные логи c 100 раз для каждого подсписка в списке ... есть ли способ обойти это?

Любая помощь по этому вопросу будет принята с благодарностью.

1 Ответ

1 голос
/ 24 марта 2020

У вас на самом деле нет списка списков, у вас есть список векторов. Со списками одно подмножество скобок вернет список, например, simul[1:3] вернет список первых 3 элементов simul, а для согласованности simul[1] вернет список первого элемента 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)

Или с помощью al oop,

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).

...