разбить кадр данных на подмножества по значениям факторов, отправить в функцию, которая возвращает класс glm, как рекомбинировать?

Благодаря функции ddply пакета plyr от Hadley мы можем взять кадр данных, разбить его на подкадры по факторам, отправить каждый в функцию, а затем объединить результаты функции для каждого подкадра данных в новый кадр данных.

Но что, если функция возвращает объект такого класса, как glm или, в моем случае, a c("glm", "lm"). Тогда их нельзя объединить в фрейм данных, не так ли? вместо этого я получаю эту ошибку

Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : cannot coerce class 'c("glm", "lm")' into a data.frame

Есть ли какая-то более гибкая структура данных, которая будет вмещать все сложные результаты класса glm моих вызовов функций, сохраняя информацию о подмножествах данных?

Или это нужно делать совсем по-другому?


person Alex Holcombe    schedule 03.06.2010    source источник
comment
Вы пробовали dlply? Выход - список.   -  person Marek    schedule 04.06.2010
comment
Вы правы, спасибо, dlply работает. Иерархический список, который возвращается, - это то, с чем я не знаком, и я не знаю, могу ли я переназначить его обратно в структуру фрейма данных каким-то масштабируемым способом, но, вероятно, это просто вопрос моего понимания нарезки списка и т. д. лучше.   -  person Alex Holcombe    schedule 04.06.2010


Ответы (1)


Просто чтобы расширить мой комментарий: plyr имеет набор функций для объединения типов ввода и вывода. Поэтому, когда ваша функция возвращает что-то непреобразуемое в data.frame, вы должны использовать list в качестве вывода. Поэтому вместо использования ddply используйте dlply.

Если вы хотите что-то сделать с каждой моделью и преобразовать результаты в data.frame, ключом будет ldply.

Давайте создадим несколько моделей, используя dlply

list_of_models <- dlply(warpbreaks, .(tension), function(X) lm(breaks~wool, data=X))
str(list_of_models, 1)
# List of 3
#  $ L:List of 13
#   ..- attr(*, "class")= chr "lm"
#  $ M:List of 13
#   ..- attr(*, "class")= chr "lm"
#  $ H:List of 13
#   ..- attr(*, "class")= chr "lm"
#  - attr(*, "split_type")= chr "data.frame"
#  - attr(*, "split_labels")='data.frame':        3 obs. of  1 variable:

Это дает list из трех lm моделей.

Используя ldply, вы можете создать data.frame, например.

  • с предсказаниями каждой модели:

    ldply(list_of_models, function(model) {
        data.frame(fit=predict(model, warpbreaks))
    })
    #     tension     fit
    # 1         L 44.5556
    # 2         L 44.5556
    # 3         L 44.5556
    
  • со статистикой по каждой модели:

    ldply(list_of_models, function(model) {
      c(
        aic = extractAIC(model),
        deviance = deviance(model),
        logLik = logLik(model),
        confint = confint(model),
        coef = coef(model)
      )
    })
    # tension aic1    aic2 deviance   logLik confint1  confint2 confint3 confint4 coef.(Intercept) coef.woolB
    # 1       L    2 98.3291  3397.78 -72.7054  34.2580 -30.89623  54.8531 -1.77044          44.5556  -16.33333
    # 2       M    2 81.1948  1311.56 -64.1383  17.6022  -4.27003  30.3978 13.82559          24.0000    4.77778
    # 3       H    2 76.9457  1035.78 -62.0137  18.8701 -13.81829  30.2411  2.26273          24.5556   -5.77778
    
person Marek    schedule 06.06.2010