내 pmap_dfc 문에 세 번째 동적 목록 요소를 추가하는 방법

Nov 25 2020

두 목록을 사용하여 시뮬레이션 출력을 생성하는 다음 작업 코드가 있습니다.

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 : 이것을 조금 더 간단하게 만들기 위해 내 질문의 단순화 된 버전을 모으고 reprex를 포함했습니다. 두 개의 목록이있는 Simulation1이 제대로 작동합니다. 세 개의 목록이있는 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)

지금 세 가지 목록에 가지고 있기 때문에 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

위의 원래 답변도 업데이트했습니다.