Мурлыканье карты несколько функций и два входа

#r #dplyr #tidyverse #purrr

Вопрос:

Я пытаюсь использовать purrr для сопоставления нескольких функций с двумя входами. Пример приведен ниже, но в идеале я хотел бы распространить его на большее количество функций. При попытке сделать это я получаю сообщение об ошибке, что входные данные не найдены, однако, даже когда я пытаюсь указать входные данные в списке функций, это не устраняет проблему.

 library(yardstick)
library(tidyverse)

funcs <- list(accuracy = yardstick::accuracy_vec,
              recall = yardstick::recall_vec)

n <- 1000
x <- as.factor(rbinom(n, 1, 0.5))
y <- as.factor(rbinom(n, 1, 0.5))

df <- tibble(true = rep(list(y), 3),
             preds = rep(list(x), 3))

df
#> # A tibble: 3 x 2
#>   true          preds        
#>   <list>        <list>       
#> 1 <int [1,000]> <int [1,000]>
#> 2 <int [1,000]> <int [1,000]>
#> 3 <int [1,000]> <int [1,000]>

df %>% map2_df(.x = true, .y = preds, .f = funcs)
#> Error in map2(.x, .y, .f, ...): object 'true' not found

funcs <- list(accuracy = ~yardstick::accuracy_vec(truth = .x, estimate = .y),
              recall = ~yardstick::recall_vec(truth = .x, estimate = .y))

df %>% map2_df(.x = true, .y = preds, .f = funcs)
#> Error in map2(.x, .y, .f, ...): object 'true' not found
 

В идеале я бы получил что-то вроде этого:

 # A tibble: 3 x 4
  true          preds         accuracy recall
  <list>        <list>           <dbl>  <dbl>
1 <int [1,000]> <int [1,000]>      0.7    0.8
2 <int [1,000]> <int [1,000]>      0.7    0.8
3 <int [1,000]> <int [1,000]>      0.7    0.8
 

Любая помощь будет очень признательна, ТИА

Ответ №1:

Вы можете использовать вложенные карты:

 df %>% 
  mutate(map2_dfr(true, preds, ~map_dfc(funcs, do.call, list(.x, .y))))
 

Ответ №2:

Я получаю ошибки, когда передаю числовые значения в функцию accuracy_vec и recall_vec . Я получаю

Ошибка: truth должен быть коэффициент, но было указано целое число..

Поэтому я меняю данные на коэффициент.

 library(tidyverse)

n <- 1000
x <- rbinom(n, 1, 0.5)
y <- rbinom(n, 1, 0.5)

df <- tibble(true = rep(list(factor(y)), 3),
             preds = rep(list(factor(x)), 3))
 

Во-вторых, каналы передают значение с левой стороны (LHS) в качестве первого аргумента функции с правой стороны. Поэтому при использовании df %>% map2_df(.x = true, .y = preds, .f = funcs) df передается неявно.

Вы можете написать пользовательскую функцию для возврата тиббла.

 funcs <- function(.x, .y) {
  tibble(accuracy = yardstick::accuracy_vec(truth = .x, estimate = .y), 
         recall =   yardstick::recall_vec(truth = .x, estimate = .y))
}
 

а затем используйте map2_df для получения одного кадра данных в качестве выходного.

 map2_df(df$true, df$preds, funcs)