pmap_dfcステートメントに3番目の動的リスト要素を追加するにはどうすればよいですか

Nov 25 2020

2つのリストを利用してシミュレーション出力を生成する次の作業コードがあります。

strategy_list <- list("s_Win","s_WinH1", "s_WinH2", "s_WinH1F1", "s_WinH2F2", "s_WinDerEx")
function_list <- list(s_win, s_winH1, s_winH2, s_winH1F1, s_winH2F2, s_winDerEx)
l <- list(strategy_list, function_list)
simulation <- pmap_dfc(l, ~ df %>%
                      transmute(!! .x := .y(entries, skill, field, win_payoff, wager_amt, Winner, exacta_payoff))) %>%
  bind_cols(df, .) 

ここで、いくつかの異なるスキルレベルでシミュレーションを実行したいので、ループを追加し、スキル入力をループからのiに置き換えて、シミュレーションのいくつかのバリエーションを作成しようとしました。

for (i in seq(from = 0.15, to=0.30, by=0.05)){
skill_list <- list(i, i, i, i, i, i)
strategy_list <- list("s_Win","s_WinH1", "s_WinH2", "s_WinH1F1", "s_WinH2F2", "s_WinDerEx")
function_list <- list(s_win, s_winH1, s_winH2, s_winH1F1, s_winH2F2, s_winDerEx)
l <- list(skill_list, strategy_list, function_list)
simulation <- pmap_dfc(l, ~ df %>%
                      transmute(!! .w !! .x := .y(entries, i, field, win_payoff, wager_amt, Winner, exacta_payoff))) %>%
  bind_cols(df, .)
}

残念ながら、これによりエラーが発生します。いくつかのバリエーションを試しましたが、コードを機能させることができないようです。

編集:以下のAtemの投稿に基づいて、コードを次のように更新しました。

for (i in seq(from = 0.15, to=0.30, by=0.05)){
strategy_list <- list("s_Win","s_WinH1", "s_WinH2", "s_WinH1F1", "s_WinH2F2", "s_WinDerEx") %>% stringr::str_c(i)
function_list <- list(s_win, s_winH1, s_winH2, s_winH1F1, s_winH2F2, s_winDerEx)
skill_list <- list(i, i, i, i, i, i)
l <- list(strategy_list, function_list, skill_list)
simulation <- pmap_dfc(l, ~ df %>%
                      transmute(!! ..1 := ..2 (entries, ..3, field, win_payoff, wager_amt, Winner, exacta_payoff))) %>%
  bind_cols(df, .)  %>% 

残念ながら、これはまだエラーを生成しています。..1および..3と同じ構文の強調表示を受け取らないため、問題は..2にあるようです。

編集2:これを少し簡単にするために、質問の簡略版をまとめて、要約を含めました。2つのリストを持つSimulation1は正常に機能します。3つのリストを持つSimulation2とループは、次のエラーメッセージで失敗します:関数 "..2"が見つかりませんでした。

``` r
library(tidyverse)
z <- 5

df <- tibble(x=1:10, y=1:10)

s_win <- function(x,y,z){
a <-rnorm(x) + x + y + 1 +z
a
}

s_win1 <- function(x,y,z){
b <-  rnorm(x) + x + y + 2 + z
b
}

s_win2 <- function(x,y,z){
c <-  rnorm(x) + x + y + 3 +z
c
}

# Simulation1 with two list works.  

strategy_list <- list("s_Win","s_Win1", "s_Win2") 
function_list <- list(s_win, s_win1, s_win2)
l <- list(strategy_list, function_list)
simulation1 <- pmap_dfc(l, ~ df %>%
                      transmute(!! .x := .y (x, y, z))) %>%
  bind_cols(df, .)  %>% 
  pivot_longer(
   cols = starts_with("s_"),
   names_to = "Strategy",
   names_prefix = "s_",
   values_to = "Value",
   values_drop_na = TRUE
 ) 
    
View(simulation1)


# Simulation 2 with thre list does not work.  Error message = could not find function "..2"

for (i in seq(from = 5, to=20, by=5)){
strategy_list <- list("s_Win","s_Win1", "s_Win2") %>% stringr::str_c(i)
function_list <- list(s_win, s_win1, s_win2)
skill_list <- list(i, i, i)
l <- list(strategy_list, function_list, skill_list)
simulation2 <- pmap_dfc(l, ~ df %>%
                      transmute(!! ..1 := ..2 (x, y, ..3))) %>%
  bind_cols(df, .)  %>% 
  pivot_longer(
   cols = starts_with("s_"),
   names_to = "Strategy",
   names_prefix = "s_",
   values_to = "Value",
   values_drop_na = TRUE
 )
}
#> Error: Problem with `mutate()` input `s_Win5`.
#> x could not find function "..2"
#> i Input `s_Win5` is `..2(x, y, ..3)`.
View(simulation2)  
#> Error in as.data.frame(x): object 'simulation2' not found
```

reprexパッケージ(v0.3.0)によって2020-11-25に作成されました

回答

1 ArtemSokolov Nov 25 2020 at 22:56

列名はに格納されますstrategy_list。これは、組み込む場所ですi

strategy_list <- list("s_Win","s_WinH1", "s_WinH2",
                      "s_WinH1F1", "s_WinH2F2", "s_WinDerEx") %>% 
                   stringr::str_c(i)

あなたは今では3つのリストを持っているのでl、あなたも使うように変更したいと思うでしょう..1..2などの代わりに、.x.y(引数の二組のためだけに充当されています):

simulation <- pmap_dfc(l, ~ df %>%
                      transmute(!! ..1 := rlang::exec(..2, entries, ..3, field, win_payoff, 
                                              wager_amt, Winner, exacta_payoff))) %>%
  bind_cols(df, .)

マイナーノート!!演算子は「引用符を外す」として知られています。これがないと、に格納さている名前を使用する代わりにtransmute、という列が作成.x .xます。違いを示す例を次に示します。

x <- "result"
mtcars %>% transmute( x = "Hello World" )
#              x
# 1  Hello World
# 2  Hello World
# ...

mtcars %>% transmute( !!x := "Hello World" )
#         result
# 1  Hello World
# 2  Hello World
# ...

..2問題に対処するための編集何らかの理由で、関数を含むpmapもの..2として解釈する際に問題があります。簡単な回避策はrlang::exec、指定された引数を使用してその関数を実行するために使用することです。

simulation2 <- pmap_dfc(l, ~ df %>%
                      transmute(!! ..1 := rlang::exec(..2, x, y, ..3))) %>%
    # ... as before

上記の元の回答も更新しました。