Wie würde ich purrr verwenden, um eine Simulation basierend auf einer Liste von Szenarien und einer Simulationsfunktion mehrmals auszuführen?

Nov 24 2020

Ich möchte tibble, df , eine Liste von Szenarien, myscenarios und eine Simulationsfunktion, simu , verwenden, um ein Ergebnis tibble zu erstellen mit:

  1. 25 Datenzeilen (fünf Zeilen für jedes Szenario)
  2. Der Ergebnisdatenrahmen sollte die folgenden Spalten enthalten: x, n, v, Szenario, Ergebnis

Ich möchte dies mit der entsprechenden Purrr-Funktion erreichen.

Der folgende Reprex enthält das Tibble, eine Liste von fünf Szenarien und die Simu-Funktion. Der Stromausgang nutzt einfach die Simu-Funktion gegen das df-Tibble.

Wäre lmap die richtige Purrr-Funktion, um dies zu erreichen? Wenn ja, müsste ich lmap in Verbindung mit mutate verwenden?

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

Erstellt am 23.11.2020 durch das reprex-Paket (v0.3.0)

Antworten

1 akrun Nov 24 2020 at 05:51

Wir können die listNamen mit mapdurchlaufen, mit assign ( :=) und evaluieren ( !!) die Ausgabe den Namen zuweisen

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

-Ausgabe

# 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

Wenn es listFunktionen gibt, die den Elementen von 'myscenarios' entsprechen, können wir beide mit durchlaufen map2und dann die Funktion (vorausgesetzt, sie haben dieselben Argumente) auf das Dataset anwenden, eine einzelne Spalte transmutemit dem ursprünglichen Dataset zurückgeben und mit diesem binden

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