我有一个复杂的函数,由于一些参数化的计算结果,该函数返回多个小标题(或数据帧)。这些小节的形状不同,所以我不能只返回一个小节。
我希望能够为每个参数组合访问不同的结果类型,因此我创建了参数组合并使用pmap_dfr
映射它们以获取结果。这在某种程度上可行,但是通过这种方式,在我的结果中,无法确定我正在查看哪种结果:
library(tidyverse)
foo <- function(.param1, .param2) {
return(tibble(
.param1 = .param1,
.param2 = .param2,
data = list(
ret1 = tibble(ret1_col1 = c(1, 2, 3), ret1_col2 = c(1, 2, 3)),
ret2 = tibble(ret2_col1 = c(1, 2, 3, 4, 5)),
ret3 = tibble(ret3_col1 = c(1, 2), ret3_col2 = c(1, 2), ret3_col3 = c(1, 2))
)
))
}
tibble::tribble(
~.param1, ~.param2,
1, 2,
3, 4
) %>%
pmap_dfr(foo)
#> # A tibble: 6 x 3
#> .param1 .param2 data
#> <dbl> <dbl> <list>
#> 1 1 2 <tibble [3 × 2]>
#> 2 1 2 <tibble [5 × 1]>
#> 3 1 2 <tibble [2 × 3]>
#> 4 3 4 <tibble [3 × 2]>
#> 5 3 4 <tibble [5 × 1]>
#> 6 3 4 <tibble [2 × 3]>
由reprex package(v0.3.0)于2019-07-16创建
例如,对于第一行,这指的是<tibble>
?
理想情况下,我会得到以下结果:
.param1 .param2 ret1 ret2 ret3
<dbl> <dbl> <list> <list> <list>
1 1 2 <tibble [3 × 2]> <tibble [5 × 1]> <tibble [2 × 3]>
2 3 4 <tibble [3 × 2]> <tibble [5 × 1]> <tibble [2 × 3]>
我该如何实现?
答案 0 :(得分:1)
如果我的理解正确,则可以对函数做一些小的修改,以标记出要创建的数据框。一种方法是仅创建一个其值具有与数据帧匹配的名称的列,即ret1
,ret2
。
library(tidyverse)
foo <- function(.param1, .param2) {
dfs <- c("ret1", "ret2", "ret3") # added here
return(tibble(
.param1 = .param1,
.param2 = .param2,
col = dfs, # added here
data = list(
tibble(ret1_col1 = c(1, 2, 3), ret1_col2 = c(1, 2, 3)),
tibble(ret2_col1 = c(1, 2, 3, 4, 5)),
tibble(ret3_col1 = c(1, 2), ret3_col2 = c(1, 2), ret3_col3 = c(1, 2))
) %>%
setNames(dfs)
))
}
然后,您可以像在其他任何列上一样在该列表列上使用spread
。
tibble::tribble(
~.param1, ~.param2,
1, 2,
3, 4
) %>%
pmap_dfr(foo) %>%
spread(key = col, value = data)
#> # A tibble: 2 x 5
#> .param1 .param2 ret1 ret2 ret3
#> <dbl> <dbl> <list> <list> <list>
#> 1 1 2 <tibble [3 × 2]> <tibble [5 × 1]> <tibble [2 × 3]>
#> 2 3 4 <tibble [3 × 2]> <tibble [5 × 1]> <tibble [2 × 3]>
答案 1 :(得分:0)
一种解决方案是不返回小标题列表,而是返回列表中的每个小标题:
return(tibble(
.param1 = .param1,
.param2 = .param2,
ret1 = list(tibble(ret1_col1 = c(1, 2, 3), ret1_col2 = c(1, 2, 3))),
ret2 = list(tibble(ret2_col1 = c(1, 2, 3, 4, 5))),
ret3 = list(tibble(ret3_col1 = c(1, 2), ret3_col2 = c(1, 2), ret3_col3 = c(1, 2)))
))
这样,pmap_dfr
可以正确收集结果。
完整示例:
library(tidyverse)
foo <- function(.param1, .param2) {
return(tibble(
.param1 = .param1,
.param2 = .param2,
ret1 = list(tibble(ret1_col1 = c(1, 2, 3), ret1_col2 = c(1, 2, 3))),
ret2 = list(tibble(ret2_col1 = c(1, 2, 3, 4, 5))),
ret3 = list(tibble(ret3_col1 = c(1, 2), ret3_col2 = c(1, 2), ret3_col3 = c(1, 2)))
))
}
tibble::tribble(
~.param1, ~.param2,
1, 2,
3, 4
) %>%
pmap_dfr(foo) %>% unnest(ret1)
#> # A tibble: 6 x 4
#> .param1 .param2 ret1_col1 ret1_col2
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1 2 1 1
#> 2 1 2 2 2
#> 3 1 2 3 3
#> 4 3 4 1 1
#> 5 3 4 2 2
#> 6 3 4 3 3
由reprex package(v0.3.0)于2019-07-16创建