2016-09-02 1 views
1

J'ai un problème pour contrôler les types d'objets alimentant la fonction de prédiction. Voici ma fonction simplifiée qui génère l'objet glm.glm `predict()` erreur: aucune méthode applicable pour 'predict' appliquée à un objet de la classe "list"

fitOneSample <- function(x,data,sampleSet) 
{ 
    #how big of a set are we going to analyze? Pick a number between 5,000 & 30,000, then select that many rows to study 
    sampleIndices <- 1:5000 

    #now randomly pick which columns to study 
    colIndices <- 1:10 

    xnames <- paste(names(data[,colIndices]),sep = "") 
    formula <- as.formula(paste("target ~ ", paste(xnames,collapse = "+"))) 
    glm(formula,family=binomial(link=logit),data[sampleIndices,]) 
} 

myFit <- fitOneSample(1,data,sampleSet) 
fits <- sapply(1:2,fitOneSample,data,sampleSet) 
all.equal(myFit,fits[,1]) #different object types 

#this works 
probability <- predict(myFit,newdata = data) 

#this doesn't 
probability2 <- predict(fits[,1],newdata = data) 
# Error in UseMethod("predict") : 
# no applicable method for 'predict' applied to an object of class "list" 

Comment accéder à la colonne fits[,1] pour que je puisse utiliser la fonction de prédire pour obtenir même résultat que je l'ai fait avec myFit?

+0

Essayez 'fits <- lapply (1: 2, fitOneSample, données, sampleSet)', puis 'probability2 < - predict (correspond à [[1]], newdata = data) '. – cryo111

+0

Merci @ cryo111. Cela a fonctionné parfaitement. –

Répondre

1

Je pense que je suis maintenant capable de récupérer votre situation.

fits <- sapply(names(trees), 
       function (y) do.call(lm, list(formula = paste0(y, " ~ ."), data = trees))) 

Il utilise intégré dans les données trees à titre d'exemple, montage trois modèles linéaires:

Girth ~ Height + Volume 
Height ~ Girth + Volume 
Volume ~ Height + Girth 

Depuis que nous avons utilisé sapply, et chaque itération retourne le même objet lm, ou une longueur-12 liste, des résultats sera simplifiée à une matrice 12 * 3:

class(fits) 
# "matrix" 

dim(fits) 
# 12 3 

indexation Matrix fits[, 1] est valide.

Si vous vérifiez str(fits[, 1]), cela ressemble presque à un objet lm normal. Mais si vous vérifiez plus loin:

class(fits[, 1]) 
# "list" 

Em? Il n'a pas de classe "lm"! En conséquence, S3 mode d'expédition échoue volonté lorsque vous appelez la fonction générique predict:

predict(x) 
#Error in UseMethod("predict") : 
# no applicable method for 'predict' applied to an object of class "list" 

Cela peut être considéré comme un bon exemple que sapply est destructeur. Nous voulons lapply, ou tout au moins, sapply(..., simplify = FALSE):

fits <- lapply(names(trees), 
       function (y) do.call(lm, list(formula = paste0(y, " ~ ."), data = trees))) 

Les résultats de lapply est plus facile à comprendre. C'est une liste de longueur 3, où chaque élément est un objet lm. Nous pouvons accéder au premier modèle via fits[[1]]. Maintenant, tout fonctionne:

class(fits[[1]]) 
# "lm" 

predict(fits[[1]]) 
#  1   2   3   4   5   6   7   8 
# 9.642878 9.870295 9.941744 10.742507 10.801587 10.886282 10.859264 10.957380 
#  9  10  11  12  13  14  15  16 
#11.588754 11.289186 11.946525 11.458400 11.536472 11.835338 11.133042 11.783583 
#  17  18  19  20  21  22  23  24 
#13.547349 12.252715 12.603162 12.765403 14.002360 13.364889 14.535617 15.016944 
#  25  26  27  28  29  30  31 
#15.628799 17.945166 17.958236 18.556671 17.229448 17.131858 21.888147 

Vous pouvez corriger votre code par

fits <- lapply(1:2,fitOneSample,data,sampleSet) 
probability2 <-predict(fits[[1]],newdata = data) 
+0

Merci pour ça. Mon principal problème était de préserver la structure pendant une boucle. Vos commentaires m'ont fait réaliser que sapply détruit la structure - bon à savoir. J'ai modifié ma fonction antérieure pour l'utiliser lapply. –