r-如何在pmap_dfc语句中添加第三个动态列表元素



我有以下工作代码,它利用两个列表来产生模拟输出:

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, .)  %>% 

不幸的是,这仍然会产生一个错误。问题似乎出在。。2,因为这没有接收到与..相同的语法高亮显示。。1和。。3.

第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

列名存储在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

我也更新了上面的原始答案。

相关内容

  • 没有找到相关文章

最新更新