1

I would like to simulate the frequency and severity over a list of parameters. Here is the case for the first item in the list:

data <- data.frame(
lamda = c(5, 2, 3),
meanlog = c(9, 10, 11), 
sdlog = c(2, 2.1, 2.2))

freq <- rpois(s, data$lamda[1])

freqsev <- lapply(freq, function(k) rlnorm(k, data$meanlog[1], sdlog = data$sdlog[1]))

freq
freqsev

How I set up a loop or an lapply statement to iterate over all the items in data? (not just the first).

Thanks.

Joseph Ireland
  • 2,465
  • 13
  • 21

1 Answers1

2

We can use map (from the purrr package, part of the tidyverse package) as follows to create list columns. The contents are now stored in the freq and freqsev columns.

library(tidyverse)

set.seed(123)

s <- 2

data2 <- data %>%
  mutate(freq = map(lamda, ~rpois(s, .x)),
         freqsev = map(freq, ~map(.x, function(k) rlnorm(k, meanlog, sdlog))))

data2$freq
# [[1]]
# [1] 4 7
# 
# [[2]]
# [1] 2 4
# 
# [[3]]
# [1] 6 0

data2$freqsev
# [[1]]
# [[1]][[1]]
# [1]    9330.247   28897.323 2605520.369   20370.283
# 
# [[1]][[2]]
# [1]    645.4047   5206.2183  22461.1778  93729.0634  46892.3129 144595.7492  10110.8606
# 
# 
# [[2]]
# [[2]][[1]]
# [1]   2665.955 938950.074
# 
# [[2]][[2]]
# [1]  21931.9763    354.2858 280122.6952   3147.6681
# 
# 
# [[3]]
# [[3]][[1]]
# [1]   957.5257 13936.3063  6265.3530  1886.0077  5927.8540  1464.5081
# 
# [[3]][[2]]
# numeric(0)

Update

Here is the way to replace values larger than equal to 500.

data3 <- data2 %>%
  mutate(capat500 = map(freqsev, ~map(.x, function(y) ifelse(y >= 500, 500, y))))
www
  • 38,575
  • 12
  • 48
  • 84
  • This is great @www, thank you very much! How could I, for example, cap these values at `500`? something like `capat500 <- ifelse(data2$freqsev >= 500, 500, data2$freqsev)` – Vincent Risington Jan 29 '19 at 18:54