Jak użyłbym purrr do uruchomienia symulacji wielokrotnie w oparciu o listę scenariuszy i funkcję symulacyjną

Nov 24 2020

Chcę użyć tibble, df , listy scenariuszy, myscenarios i funkcji symulacyjnej simu , aby utworzyć wynikową tibble z:

  1. 25 wierszy danych (pięć wierszy dla każdego scenariusza)
  2. Ramka danych wynikowych powinna zawierać następujące kolumny: x, n, v, scenario, result

Chciałbym to osiągnąć za pomocą odpowiedniej funkcji mruczenia.

Poniższe reprex zawiera tibble, listę pięciu scenariuszy i funkcję simu. Wyjście prądowe po prostu wykorzystuje funkcję simu przeciwko tibble df.

Czy lmap byłaby właściwą funkcją mruczenia, aby to osiągnąć? Jeśli tak, czy musiałbym używać lmap w połączeniu z 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

Utworzono 23.11.2020 r. Przez pakiet reprex (v0.3.0)

Odpowiedzi

1 akrun Nov 24 2020 at 05:51

Możemy wykonać pętlę nad listnazwami za pomocą map, użyj assign ( :=) podczas oceniania ( !!), aby przypisać wyjście do nazw

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

-wynik

# 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

Jeśli istnieją listfunkcje, które odpowiadają elementom `` myscenarios '', możemy zapętlić oba z, map2a następnie zastosować funkcję (zakładając, że mają te same argumenty), na zestawie danych zwrócić pojedynczą kolumnę z transmuteoryginalnym zbiorem danych i powiązać z nim

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