无法从 purr::pmap 或 purr:map2 中的输入列表访问字符串元素

Can't access string elements from input list in purr::pmap or purr:map2

我在访问列表的字符串值作为 purr 函数的参数时遇到了一个棘手的问题。

我的目标是将我放入一个输入列表的两个向量的字符串元素的所有排列组合(用于输出文件名):

target.labels <- c("Prefix_A", "Prefix_B")
features.sets <- c("Suffix_X", "Suffix_Y")

input.list <- expand.grid(x=target.labels, y=features.sets)

预期结果应如下所示:

"Prefix_A-Suffix_X" "Prefix_B-Suffix_X" "Prefix_A-Suffix_Y" "Prefix_B-Suffix_Y"

这是我尝试过的:

library(dplyr)
library(purrr)

fun1 <- function(x,y) { paste0(c(x, y), collapse = "-") }
fun2 <- function(x,y) { paste(x, y, sep = "-") }
fun3 <- function(x,y) { glue::glue("x = {x}, y = {y}") }


input.list %>% pmap_chr(fun1)
## [1] "1-1" "2-1" "1-2" "2-2"

input.list %>% pmap_chr(fun2)
## [1] "1-1" "2-1" "1-2" "2-2

input.list %>% pmap_chr(fun3)
## [1] "x = 1, y = 1" "x = 2, y = 1" "x = 1, y = 2" "x = 2, y = 2"

input.list %>% pmap_chr(~paste(.x, .y, sep = "-"))
## [1] "1-1" "2-1" "1-2" "2-2"

如您所见,purr::pmap 函数仅检索元素的索引值而不是字符串值。 另一方面,它可能不是 purr 特有的,因为应用函数显示了同样的问题:

mapply(fun1, input.list$x, input.list$y)
## [1] "1-1" "2-1" "1-2" "2-2"

一种预感是,paste0() 或 paste() 中隐藏的 c() 函数以某种方式阻止了对字符串值的访问 - 但仅与 purr:pmap 结合使用,而不是与 [=39= 结合使用]!

所以这有效:

map2_chr(.x = input.list$x, .y = input.list$y, ~paste(.x, .y, sep = "-"))

## [1] "Prefix_A-Suffix_X" "Prefix_B-Suffix_X" "Prefix_A-Suffix_Y"
## [4] "Prefix_B-Suffix_Y"

我的直觉是这个问题可能与 NSE(非标准评估)有关,但我无法弄清楚,因为 purr:map2 按预期工作。

我将不胜感激为什么会发生这种情况——以及如何让它与purr:pmap一起工作。

基本函数 expand.grid 正在将您的列转换为因子。由于您已经在使用 tidyverse 函数,因此请使用 tidy 等价物 crossing 而不是

input.list <- crossing(x=target.labels, y=features.sets)

那么 fun1fun1 应该可以正常工作。因子的问题在于它们基本上作为整数存储在 R 中,因此它们更可能被转换为数字而不是字符。

这里的expand.grid列如果用stringsAsFactors = FALSE可以改成characterclass,然后用pmap就可以paste每行中的元素

library(purrr)
input.list <- expand.grid(x=target.labels, y=features.sets, stringsAsFactors = FALSE)
pmap_chr(input.list, paste, collapse="-")
#[1] "Prefix_A Suffix_X" "Prefix_B Suffix_X" "Prefix_A Suffix_Y" "Prefix_B Suffix_Y"