Не удается получить доступ к строковым элементам из списка ввода в purr::pmap или purr:map2
У меня есть сложная проблема, чтобы получить доступ к строковым значениям списка в качестве аргумента для функций мурлыкания.
Моя цель - объединить все перестановки строковых элементов двух векторов (для использования в выходном имени файла), которые я поместил в один входной список:
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 показывают ту же проблему:
mapply(fun1, input.list$x, input.list$y)
## [1] "1-1" "2-1" "1-2" "2-2"
Одним из предположений является то, что скрытая функция c() в paste0() или paste() запрещает доступ к строковым значениям - но только в сочетании с 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 ответа
Базовая функция expand.grid
превращает ваши столбцы в факторы. Поскольку вы уже используете функции Tidyverse, используйте эквивалент Tidy crossing
вместо
input.list <- crossing(x=target.labels, y=features.sets)
затем fun1
или же fun1
должно работать нормально. Проблема с факторами заключается в том, что они в основном хранятся как целые числа в R, поэтому они более вероятно будут преобразованы в числа, чем в символы.
Здесь expand.grid
столбцы могут быть изменены на character
класс, если мы используем stringsAsFactors = FALSE
, а затем с 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"