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

时间:2019-02-06 16:08:18

标签: r purrr mapply pmap

我有一个棘手的问题来访问列表的字符串值作为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函数仅检索元素的索引值,而不是字符串值。 另一方面,因为apply函数显示了相同的问题,所以purr可能不是特定的:

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

一种预感是,paste0()或paste()中隐藏的c()函数会阻止访问字符串值-但只能与purr:pmap结合使用,而不能与purr:map2结合使用!

这可行:

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一起使用。

2 个答案:

答案 0 :(得分:1)

基本功能expand.grid将您的专栏变成要素。由于您已经在使用tidyverse函数,请改用等效的crossing

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

然后fun1fun1应该可以正常工作。因素的问题在于,它们基本上存储为R中的整数,因此比字符更容易转换为数字。

答案 1 :(得分:0)

如果我们使用expand.grid,则character列可以更改为stringsAsFactors = FALSE类,然后使用pmap可以paste每行中的元素< / p>

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"