J'ai écrit une fonction pour prendre les coefficients d'un modèle (linéaire) et les appliquer sur les variables d'origine pour donner une trame de données de termes qui, lorsqu'ils sont additionnés, sera équivalente au résultat de predict(). Cette capacité me semble utile pour mieux comprendre l'influence de chaque variable (ou plus complexe terme d'interaction, etc) sur le modèle.R: appliquer les coefficients du modèle à travers les variables dans le modèle, une meilleure façon?
Y a-t-il un meilleur moyen? Je me sens comme un hack. J'ai regardé dans le str() des modèles, et ne vois pas une solution plus simple pour le moment. Tricky partie est d'attraper et d'appliquer des termes d'interaction.
library(plyr)
nospredict = function(model, data = model$model, sorted = TRUE) { # model is model (from lm, glm...), data is data.frame to be applied to
c = coef(model) # model must support coef()
my.names = names(c) = gsub(':', '*', names(c)) # ':' equals multiplication in formulas, coefs
data = data[ , colnames(data) %in% my.names] # don't do the attach() below with a zillion variables...
final.out = adply(data, 1, function(y) { # did I mention I like plyr?
attach(as.list(y), warn.conflicts = FALSE) # so you can do eval algebra blackRmagic
out = ldply(my.names, function (x) { # did I mention...
Intercept = 1 # (Intercept) from model is a constant, multiply it by 1
eval( parse( text = paste(c[x], "*", x) ) ) }) # blackRmagic
out = as.data.frame(t(out)) ; colnames(out) = my.names ; out
})
rownames(final.out) = rownames(data)
final.out$Predict = predict(model, data) ## add predict() as column
if (sorted) {
final.out[order(final.out$Predict), ] ## return df sorted by predict()
}
final.out
}
set.seed(10538)
df = data.frame(a = 1:10, b = rnorm(10), c = 1:10 + rnorm(10))
lmf = lm(c ~ a * b, data = df)
> df
a b c
1 1 -0.41184664 1.3739709
2 2 1.06464586 0.8975101
3 3 -0.07522363 3.4910425
4 4 1.21643049 2.8856876
5 5 0.34061917 4.3851439
6 6 -1.00020786 6.1836535
7 7 -0.36954963 6.4734150
8 8 -1.47754640 6.8150569
9 9 -0.19312147 9.6432687
10 10 2.32220098 9.4276813
> nospredict(lmf)
(Intercept) a b a*b Predict
1 0.09801818 0.9282185 0.48332671 -0.05438652 1.4551769
2 0.09801818 1.8564370 -1.24942570 0.28118420 0.9862137
3 0.09801818 2.7846555 0.08827944 -0.02980103 2.9411521
4 0.09801818 3.7128740 -1.42755405 0.64254425 3.0258824
5 0.09801818 4.6410925 -0.39973700 0.22490279 4.5642765
6 0.09801818 5.5693110 1.17380385 -0.79249635 6.0486367
7 0.09801818 6.4975295 0.43368863 -0.34160685 6.6876294
8 0.09801818 7.4257480 1.73398922 -1.56094237 7.6968130
9 0.09801818 8.3539665 0.22663962 -0.22952439 8.4490999
10 0.09801818 9.2821850 -2.72524198 3.06658890 9.7215501
sort final par predict() valeurs ne fonctionnant pas ici, correction triviale, pas important pour la question. –
Bien sûr, l'exemple reproductible ci-dessus n'est que cela. Je suis à la recherche d'une solution qui soit généralisable sur la plupart ou toutes les formules de modèles (sans savoir que le modèle avait «a» et «b» dedans, etc.). –