¿Cómo usaría purrr para ejecutar una simulación varias veces en función de una lista de escenarios y una función de simulación?

Nov 24 2020

Quiero usar tibble, df , una lista de escenarios, myscenarios y una función de simulación, simu , para crear un tibble de resultado con:

  1. 25 filas de datos (cinco filas para cada escenario)
  2. El marco de datos de resultado debe incluir las siguientes columnas: x, n, v, escenario, resultado

Me gustaría lograr esto usando la función purrr apropiada.

El siguiente reprex proporciona el tibble, una lista de cinco escenarios y la función simu. La salida de corriente simplemente utiliza la función simu contra el tibble df.

¿Lmap sería la función purrr correcta para lograr esto? Si es así, ¿tendría que usar lmap junto con mutate?

library(tidyverse)
df <- tibble(x= 1:5, 
             n= c("Jim","John","Jane","Jay","Jack"),
             v= 11:15)

myscenarios <- list("one", "two", "three", "four", "five")

simu <- function(x, v){
  x * v + sample(1:10, 1)
} 

result <- df %>% 
  mutate(result = simu(x, v))

result
#> # A tibble: 5 x 4
#>       x n         v result
#>   <int> <chr> <int>  <int>
#> 1     1 Jim      11     21
#> 2     2 John     12     34
#> 3     3 Jane     13     49
#> 4     4 Jay      14     66
#> 5     5 Jack     15     85

Creado el 2020-11-23 por el paquete reprex (v0.3.0)

Respuestas

1 akrun Nov 24 2020 at 05:51

Podemos recorrer el listde los nombres con map, use assign ( :=) mientras evaluamos ( !!) para asignar la salida a los nombres

library(dplyr)
library(purrr)
map_dfc(myscenarios, ~ df %>% 
                   transmute(!! .x := simu(x, v))) %>%
      bind_cols(df, .)

-salida

# A tibble: 5 x 8
#      x n         v   one   two three  four  five
#  <int> <chr> <int> <int> <int> <int> <int> <int>
#1     1 Jim      11    16    17    20    13    15
#2     2 John     12    29    30    33    26    28
#3     3 Jane     13    44    45    48    41    43
#4     4 Jay      14    61    62    65    58    60
#5     5 Jack     15    80    81    84    77    79

Si hay listfunciones que corresponden a los elementos de 'myscenarios', podemos recorrer ambos con map2y luego aplicar la función (asumiendo que tienen los mismos argumentos), en el conjunto de datos, devolver una sola columna con transmutey enlazar con el conjunto de datos original

lstfn <- list(simu, simu, simu, simu, simu)
map2_dfc(myscenarios, lstfn, ~ df %>%
         transmute(!! .x := .y(x, v))) %>%
     bind_cols(df, .)