2016-09-14 2 views
2

Я пытаюсь загрузить пример модели, а затем вычислять статистику, не перегружая модели каждый раз. Я могу сделать это хорошо, если я рассчитываю r2 внутри первого do(), но я хотел бы знать, как получить доступ к данным.bootstrap по группам и вычислять статистику

library(dplyr) 
library(tidyr) 
library(modelr) 
library(purrr) 

allmdls <- 
    mtcars %>% 
    group_by(cyl) %>% 
    do({ 
    datsplit=crossv_mc(.,10) 
    mdls=list(map(datsplit$train, ~glm(hp~disp,data=.,family=gaussian(link='identity')))) 
    data_frame(datsplit=list(datsplit),mdls) 
    }) 

и теперь что-то вроде:

allmdls %>% 
    by_slice(dmap,.f=map2_dbl(.$mdls,.$datsplit$test,rsquare)) 

, но я получаю

Error: .y is not a vector (NULL)

или

allmdls %>% 
    group_by(cyl) %>% 
    do({ 
    map2_df(.x=.$mdls, .y=.$datsplit, .f=map2_dbl(.x=.x,.y=.y$test,.f=rsquare)) 
    }) 

Error in map2_dbl(.x = .x, .y = .y$test, .f = rsquare) : object '.x' not found

I C похоже, что синтаксис правильный.

help? Благодаря

EDIT: Благодаря @ aosmith свой комментарий, я создал несколько более простое решение:

mtcars %>% 
    group_by(cyl) %>% 
    do({ 
    datplit=crossv_mc(.,10) %>% 
     mutate(mdls=map(train, ~glm(hp~disp,data=.)), 
      r2=map2_dbl(mdls,test,rsquare) 
      pctmae=map2_dbl(mdls,test,function(model,data) {mae(model,data)/mean(model$model$hp,na.rm=T)*100}) 
    ) 
    }) 
+1

Этот список списков, кажется realtively с трудом работать. Вы можете сделать mutate (allmdls, rsq = map2 (mdls, map (datsplit, "test"), ~ map2 (.x, .y, rsquare))) 'с вложенными' map2 ', поэтому вы работаете над самым внутренним списки. Возможно, есть что-то, что вы можете сделать и с 'at_depth', но не уверен, работая с несколькими списками списков, подобных этому. – aosmith

+0

@aosmith Я раскрыл вариант вашего решения, который проще и в основном работает так, что благодаря вдохновению. Я согласен, что списки в списках не идеальны. Как вы узнали/что происходит с «тестом» в кавычках? – Dominik

+0

Прохладный, вы должны положить его в качестве решения. 'Map (datsplit," test ")' it для извлечения столбца теста из 'datsplit' в качестве обозначения знака доллара и скобок экстента не работает. Документация для 'map' имеет довольно хорошее объяснение этого для' .f'. – aosmith

ответ

2

Одним из вариантов является использование map2 в mutate. Поскольку вы используете списки списков, я получил вложенные map2 s, чтобы получить доступ к самым сокровенным спискам. Я вытащил данные test через map(datsplit, "test"), так как для меня не работали ни оператор знака доллара, ни скобки экстента.

mutate(allmdls, rsq = map2(mdls, map(datsplit, "test"), ~map2_dbl(.x, .y, rsquare))) 

Вот еще один вариант, который позволяет избежать вложенных списков все вместе:

mtcars %>% 
    split(.$cyl) %>% 
    map_df(crossv_mc, 10, .id = "cyl") %>% 
    mutate(models = map(train, ~glm(hp ~ disp, data = .x)), 
      rsq = map2_dbl(models, test, rsquare)) 
1

@aosmith ответил на мой вопрос, но здесь более простое решение в целом

mtcars %>% 
    group_by(cyl) %>% 
    do({ 
    datplit=crossv_mc(.,10) %>% 
     mutate(mdls=map(train, ~glm(hp~disp,data=.)), 
      r2=map2_dbl(mdls,test,rsquare) 
      pctmae=map2_dbl(mdls,test,function(model,data) {mae(model,data)/mean(model$model$hp,na.rm=T)*100}) 
    ) 
    }) 
Смежные вопросы