Использование purrr :: map для функции, которая требует спецификации столбца - PullRequest
1 голос
/ 09 апреля 2020

Я хотел бы использовать purrr :: map () для запуска предварительно упакованной функции fishmethods :: deplet

Набор данных имеет несколько лет (см. Образец ниже), и мне нужно подбирать модель отдельно для каждого года .

b <- structure(list(Year = c(2012, 2012, 2012, 2012, 2015, 2015, 2015, 
2015), BF_AYAs_count = c(37, 12, 7, 8, 13, 4, 3, 6), BF_noT_effort = c(0.445138888899237, 
0.343750000007276, 0.51597222223063, 0.444444444437977, 0.613194444456894, 
0.437499999992724, 0.374999999992724, 0.607638888897782)), row.names = c(NA, 
-8L), class = c("tbl_df", "tbl", "data.frame"))

deplet ожидает следующие входные данные (catch = NULL, усилия = NULL, method = "l") и выводит список X.out, где X == метод. Для моих целей я хотел бы получить результаты (например, l.out $ results) по годам и поместить их в информационный блок. Вот код, который я пробовал, который возвращает Error in deplet(catch = BF_AYAs_count, effort = BF_noT_effort, method = "l") : object 'BF_AYAs_count' not found Я предполагаю, что это проблема, связанная с тем, как функция deplet () ожидает ввод данных, так как этот код работает нормально, если я заменяю map(data, ~lm(BF_AYAs_count~BF_noT_effort, data=.).

library(tidyverse)
library(fishmethods)

bf_AYA_popest <- b %>% 
  nest(-Year) %>% 
  mutate(fit=map(data, deplet(catch=BF_AYAs_count,effort=BF_noT_effort, method="l")),
         results = l.out$results) %>% 
  unnest()

1 Ответ

0 голосов
/ 10 апреля 2020

ОБНОВЛЕНИЕ Чтобы обойти deplet () проблему невозможности присвоить результаты deplet объекту, мы можем заключить deplet в нашу собственную функцию, которая фактически возвращает объект l.out, который он всегда создает объект, который мы создаем. Затем мы можем изменить и отобразить наш новый дуплет так, как вы изначально хотели:

deplet2 <- function(...){
  deplet(...)
  return(l.out)
}

bf_AYA_popest <- b %>% 
  nest(data = c(BF_AYAs_count, BF_noT_effort)) %>% 
  mutate(fit = map(data, ~deplet2(catch = .$BF_AYAs_count,
                                 effort = .$BF_noT_effort,
                                 method ="l")),
         results = map(fit, "results"))

СТАРЫЙ Я предвосхищу это, сказав, что никогда не использовал пакет fishmethods или функцию deplet () , Я думаю, проблема в том, что я не смог присвоить результаты функции deplet () объекту (т. Е. X <- deplet () всегда возвращал x = NULL, и объект 'l.out' ВСЕГДА создавался). Из-за этого я не уверен, что это будет хорошо играть внутри вызова mutate (). В итоге я не получил никаких ошибок, и код работал бы с картой внутри mutate, но результаты всегда были бы равны NULL (я думаю, по причинам, указанным выше - неспособность выбрать объект, в котором сохраняются результаты). </p>

Если вы открыты для этого, возможно, альтернативным предложением было бы просто использовать for-l oop и создать список результатов отдельно, а затем преобразовать весь список во вложенный фрейм данных:

#nest the count and effort data
bf_AYA_popest <- b %>% 
  nest(data = c(BF_AYAs_count, BF_noT_effort))

#create an empty list to store results
results_list <- vector("list")
#loop through rows of nested dataframes giving the data to deplete
for(i in 1:nrow(bf_AYA_popest)){

  deplet(catch = bf_AYA_popest$data[[i]]$BF_AYAs_count, 
         effort = bf_AYA_popest$data[[i]]$BF_noT_effort,
         method ="l")
  #each time deplet runs it makes an l.out
  results_list[[i]] <- l.out$results  #catch the ouput and store in list
  #the next run through l.out is overwrritten 
}

#add the list as a  column to the original nested df
bf_AYA_popest <- bf_AYA_popest %>% 
  mutate(fit = results_list)

Это была моя попытка выполнить эту работу внутри вызова mutate:

bf_AYA_popest <- b %>% 
  nest(data = c(BF_AYAs_count, BF_noT_effort)) %>% 
  mutate(fit = map(data, ~deplet(catch = .$BF_AYAs_count,
                                 effort = .$BF_noT_effort,
                                 method ="l")))

Не было выдано никаких ошибок, но результаты были в столбце NULL:

# A tibble: 2 x 3
   Year data             fit   
  <dbl> <list>           <list>
1  2012 <tibble [4 × 2]> <NULL>
2  2015 <tibble [4 × 2]> <NULL>

И я бы получил объект l.out, заполненный в моей глобальной среде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...