Eroare R care spune „Modelele nu au fost toate adaptate la aceeași dimensiune a setului de date” (Programare, R, Glm, Lm, Anova)

REnthusiast a intrebat.

Am creat două modele liniare generalizate după cum urmează:

glm1 <-glm(Y ~ X1 + X2 + X3, family=binomial(link=logit))

glm2 <-glm(Y ~ X1 + X2, family=binomial(link=logit))

Apoi am folosit anova funcție:

anova(glm2,glm1)

dar primesc un mesaj de eroare:

„Eroare în anova.glmlist(c(list(object),dotargs), dispersie = dispersie, :
modelele nu au fost toate ajustate la aceeași dimensiune a setului de date”

Ce înseamnă acest lucru și cum pot rezolva acest lucru? Am attacheditat setul de date la începutul codului meu, astfel încât ambele modele să funcționeze pe baza aceluiași set de date.

Comentarii

  • În plus, nu utilizați attach(). –  > Por Domnule O.
  • De asemenea, presupun că ați folosit glm(Y~X1...) și nu doar (Y~X1...)? Și de ce aveți virgule care separă variabilele? –  > Por Domnule O.
  • Da, am folosit asta. Îmi cer scuze că nu am postat-o corect aici înainte. Aveți vreo idee despre ce ar putea fi greșit? –  > Por REnthusiast.
  • Fără să vă văd datele sau codul, nu. Folosind attach ar putea cauza cu siguranță această problemă. –  > Por Domnul O.
  • trebuie să folosiți data=YourData în glm, , și nu puteți folosi virgule pentru a separa astfel variabilele. –  > Por Señor O.
6 răspunsuri
Greg Snow

Principala cauză a acestei erori este atunci când există valori lipsă în una sau mai multe dintre variabilele predictoare. În versiunile recente ale R, acțiunea implicită este de a omite toate rândurile care au valori lipsă (precedenta acțiune implicită era de a produce o eroare). Astfel, de exemplu, dacă cadrul de date are 100 de rânduri și există o valoare lipsă în X3, atunci modelul glm1 se va adapta la 99 de rânduri de date (eliminând rândul în care X3 lipsește), dar obiectul glm2 se va adapta la toate cele 100 de rânduri de date (deoarece nu utilizează X3, nu este nevoie să fie eliminate rânduri).

Deci, atunci anova vă dă o eroare deoarece cele 2 modele au fost adaptate la seturi de date diferite (și cum se calculează gradele de libertate etc.).

O soluție este să creați un nou cadru de date care să aibă doar coloanele care vor fi utilizate în cel puțin unul dintre modelele dvs. și să eliminați toate rândurile cu valori lipsă (funcția na.omit sau na.exclude va face acest lucru mai ușor), apoi potriviți ambele modele la același cadru de date care nu are nicio valoare lipsă.

Alte opțiuni ar fi să vă uitați la instrumentele de imputare multiplă sau la alte modalități de tratare a datelor lipsă.

Comentarii

  • Vă mulțumim pentru acest lucru, a fost foarte explicativ. Se pare că funcționează atunci când am încetat să mai folosesc attach și am ales să specific datele în fiecare glm. Funcționează acest lucru doar din întâmplare? De asemenea, caut să obțin o valoare p din anova între glm1 și diverse alte glm. Cum pot face acest lucru? –  > Por REnthusiast.
  • @Denis, Cu attach este posibil să fi avut o variabilă cu același nume în mediul global/spațiul de lucru care încurca lucrurile. Unul dintre motivele pentru care nu trebuie să folosiți attach. Pentru a obține o valoare p din anova adăugați test="Chisq", , consultați ?anova.glm pentru detalii (și asigurați-vă că sunteți mulțumit de ipoteze). –  > Por Greg Snow.
landroni

Pentru a evita "models were not all fitted to the same size of dataset" eroare, trebuie să potriviți ambele modele pe exact același subset de date. Există două modalități simple de a face acest lucru:

  • fie folosiți data=glm1$model în a doua potrivire a modelului
  • fie să recuperați setul de date corect subansamblat utilizând data=na.omit(orig.data[ , all.vars(formula(glm1))]) în a doua ajustare a modelului

Iată un exemplu reproductibil care utilizează lm (pentru glm aceeași abordare ar trebui să funcționeze) și update:

# 1st approach
# define a convenience wrapper
update_nested <- function(object, formula., ..., evaluate = TRUE){
    update(object = object, formula. = formula., data = object$model, ..., evaluate = evaluate)
}

# prepare data with NAs
data(mtcars)
for(i in 1:ncol(mtcars)) mtcars[i,i] <- NA

xa <- lm(mpg~cyl+disp, mtcars)
xb <- update_nested(xa, .~.-cyl)
anova(xa, xb)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

# 2nd approach
xc <- update(xa, .~.-cyl, data=na.omit(mtcars[ , all.vars(formula(xa))]))
anova(xa, xc)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

A se vedea, de asemenea:

  • Cum se actualizează modelul `lm` sau `glm` pe același subset de date?

CoderGuy123

Soluția este de a utiliza:

glm1 <-glm(Y ~ X1 + X2 + X3, family = binomial(link = logit), na.action = na.exclude)
glm2 <-glm(Y ~ X1 + X2, family = binomial(link = logit), na.action = na.exclude)

anova(glm2,glm1)

Acest lucru va face ca R să includă cazurile cu date lipsă (NA) în modelul ajustat. Acest lucru asigură faptul că seturile de date sunt identice în diferite modele ajustate, indiferent de modul în care sunt distribuite datele lipsă.

Comentarii

  • Adresa na.exclude abordare nu va funcționa neapărat. Încercați acest lucru: mtcars[1,2] <- NA; xa <- lm(mpg~cyl+disp, mtcars, na.action = na.exclude); xaa <- lm(mpg~disp, mtcars, na.action = na.exclude); anova(xa, xaa) –  > Por landroni.
  • Aveți dreptate. Nu funcționează în acest caz. Cu toate acestea, se asigură că predict introduce NAs pentru punctele de date care au valori lipsă în date. Citind documentația pentru na.exclude se observă că acest lucru funcționează numai pentru naresid și napredict care sunt conectate la resid și predict. Se pare că, anova utilizează altceva. Aparent, va trebui să se facă mai întâi o subansamblare la cazurile complete, de exemplu, folosind na.omit. Cel puțin, asta este sfatul dat aici. –  > Por CoderGuy123.
  • Există cel puțin două abordări simple pentru a face acest lucru, pe care le discut în acest răspuns. –  > Por landroni.
IRTFM

Bănuiesc că ai vrut să scrii:

glm1 <-glm(Y ~ X1+X2+X3, family=binomial(link=logit))

glm2 <-glm(Y ~ X1 + X2, family=binomial(link=logit))

Interfața formulei pentru funcțiile de regresie R nu recunoaște virgulele ca adăugând covariate la RHS a formulei. Și nu folosiți attach(); utilizați argumentul date pentru funcțiile de regresie.

Comentarii

  • Da, am făcut toate acestea și eroarea pare să apară în continuare. De asemenea, am introdus: na.omit=na.pass pentru a vedea dacă celulele goale din datele mele sunt tratate diferit în R, dar fără succes. Aveți vreo idee despre ce aș putea greși? –  > Por REnthusiast.
  • Eu aș folosi un data argument care să fie același pentru ambele glm apeluri: na.omit(YourData[ , c(„Y” , „X1”, „X2”, „X3”)])`. În acest fel, eliminați „cazurile suplimentare” prezente pentru X1 și X2 care nu se regăsesc în X3. –  > Por IRTFM.
  • Să pun acest glm1 <-glm(Y ~ X1+X2+X3, family=binomial(link=logit), na.omit(YourData[ , c(„Y” , „X1”, „X2”, „X3”)])) atunci când definesc ambele glm? –  > Por REnthusiast.
  • Argumentul datelor ar trebui să fie același, iar formulele ar trebui să fie diferite. –  > Por IRTFM.
cpt. couteau

Cauza este bine descrisă de Greg Snow. O soluție alternativă și foarte ușoară este adăugarea unei noi variabile, care să corespundă cu NA-urile variabilei problematice și, în rest, cu valoarea 1. Includeți-o în ambele modele și R va exclude aceleași rânduri în ambele modele (–> seturile de date se vor potrivi).

Comentarii

  • Nici unul dintre aceste răspunsuri nu pare să funcționeze în acest caz_fit4=lm(ctmax~ta+ratectmax,data=x,na.action = na.exclude)# rectiliniar fit5=lme(ctmax~poly(ta,2)+ratectmax,random=~1|col,data=x,na.action = na. exclude) fit6=lme(ctmax~poly(ta,3)+ratectmax,random=~1|col,data=x,na.action = na.exclude) fit7=lme(ctmax~poly(ta,4)+ratectmax,random=~1|col,data=x,na.action = na.exclude) anova(fit4,fit5,fit6,fit7) – se obține aceeași eroare, fără date lipsă. –  > Por Agus camacho.
J.Sabree

Cred că cel mai simplu mod de a gestiona această situație fără a imputa valorile lipsă este de a crea un nou set de date utilizând funcția drop_na() a lui tidyr.

Pentru această funcție, puneți toate variabilele de care veți avea nevoie în modelul final în interiorul porțiunii drop_na(), iar aceasta va elimina toate rândurile care au valori lipsă în orice variabilă relevantă:

library(tidyr) #load in drop_na()

mtcars[1,2] <- NA #makes the first row of the cyl column become NA to illustrate

no_missing <- mtcars %>%
  drop_na(cyl)

glimpse(no_missing) #note, you only have 31 obs instead of 32 now

drop_na() funcționează, de asemenea, pe mai multe coloane:

library(tidyr)

mtcars[1,2] <- NA #makes the first row of the cyl column become NA to illustrate
mtcars[3,1] <- NA #makes the 3rd row of the mpg column become NA to illustrate

no_missing_2 <- mtcars %>%
  drop_na(mpg, cyl)

glimpse(no_missing_2) #now, you only have 30 obs

Rulând drop_na() cu toate variabilele pe care le veți utiliza în cel mai complex model al dumneavoastră, vă veți asigura că utilizați același set de date.

Tags:, , ,