Ddply с функцией lm()
Привет, ребята, как я могу использовать функцию ddply для линейной модели:
x1 <- c(1:10, 1:10)
x2 <- c(1:5, 1:5, 1:5, 1:5)
x3 <- c(rep(1,5), rep(2,5), rep(1,5), rep(2,5))
set.seed(123)
y <- rnorm(20, 10, 3)
mydf <- data.frame(x1, x2, x3, y)
require(plyr)
ddply(mydf, mydf$x3, .fun = lm(mydf$y ~ mydf$X1 + mydf$x2))
Генерирует эту ошибку:
Ошибка в файле model.frame.default(formula = mydf $y ~ mydf $X1 + mydf $x2, drop.unused.levels = TRUE): недопустимый тип (NULL) для переменной 'mydf $X1'
Цените свою помощь.
Ответы
Ответ 1
Вот что вам нужно сделать.
mods = dlply(mydf, .(x3), lm, formula = y ~ x1 + x2)
mods - это список из двух объектов, содержащих результаты регрессии. вы можете извлечь все, что вам нужно из модов. например, если вы хотите извлечь коэффициенты, вы можете написать
coefs = ldply(mods, coef)
Это дает вам
x3 (Intercept) x1 x2
1 1 11.71015 -0.3193146 NA
2 2 21.83969 -1.4677690 NA
ИЗМЕНИТЬ. Если вы хотите ANOVA
, то вы можете просто сделать
ldply(mods, anova)
x3 Df Sum Sq Mean Sq F value Pr(>F)
1 1 1 2.039237 2.039237 0.4450663 0.52345980
2 1 8 36.654982 4.581873 NA NA
3 2 1 43.086916 43.086916 4.4273907 0.06849533
4 2 8 77.855187 9.731898 NA NA
Ответ 2
То, что Рамнатэ эксплантирует, точно соответствует действительности. Но я кое-что уточню.
ddply
ожидает кадр данных и возвращает фрейм данных. Функция lm()
принимает кадр данных как входной сигнал, но возвращает возвращаемый объект линейной модели. Вы можете видеть это, посмотрев документы для lm через ?lm
:
Значение
lm возвращает объект класса "lm" или для нескольких ответов класса c ( "mlm", "lm" ).
Таким образом, вы не можете просто перетащить объекты lm в фрейм данных. Ваш выбор заключается в принуждении вывода lm
к кадру данных или вы можете перетащить объекты lm в список вместо кадра данных.
Итак, чтобы проиллюстрировать оба варианта:
Здесь, как перетащить объекты lm в список (очень похоже на то, что иллюстрировал Рамнат):
outlist <- dlply(mydf, "x3", function(df) lm(y ~ x1 + x2, data=df))
С другой стороны, если вы хотите извлечь только коэффициенты, вы можете создать функцию, которая запускает регрессию, а затем возвращает только коэффициенты в виде фрейма данных, например:
myLm <- function( formula, df ){
lmList <- lm(formula, data=df)
lmOut <- data.frame(t(lmList$coefficients))
names(lmOut) <- c("intercept","x1coef","x2coef")
return(lmOut)
}
outDf <- ddply(mydf, "x3", function(df) myLm(y ~ x1 + x2, df))
Ответ 3
Используйте этот
mods <- dlply(mydf, .(x3), lm, formula = y ~ x1 + x2)
coefs <- llply(mods, coef)
$`1`
(Intercept) x1 x2
11.7101519 -0.3193146 NA
$`2`
(Intercept) x1 x2
21.839687 -1.467769 NA
anovas <- llply(mods, anova)
$`1`
Analysis of Variance Table
Response: y
Df Sum Sq Mean Sq F value Pr(>F)
x1 1 2.039 2.0392 0.4451 0.5235
Residuals 8 36.655 4.5819
$`2`
Analysis of Variance Table
Response: y
Df Sum Sq Mean Sq F value Pr(>F)
x1 1 43.087 43.087 4.4274 0.0685 .
Residuals 8 77.855 9.732
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1