2017-03-26 42 views
10

używam modele glmer logitowe użyciu pakietu lme4. Interesują mnie różne dwu- i trójdrożne efekty interakcji i ich interpretacje. Aby uprościć, interesują mnie tylko stałe współczynniki efektów.glmer logarytmicznej - efekty interakcji w skali prawdopodobieństwa (replikowania `` ze skutkami w predict`)

udało mi się wymyślić kodu obliczyć i wykreślić te skutki w skali logit, ale mam problemy przekształcając je do przewidywanej skali prawdopodobieństwa. Ostatecznie chciałbym powtórzyć wyjście pakietu effects.

Przykład opiera się na UCLA's data on cancer patients.

library(lme4) 
library(ggplot2) 
library(plyr) 

getmode <- function(v) { 
    uniqv <- unique(v) 
    uniqv[which.max(tabulate(match(v, uniqv)))] 
} 

facmin <- function(n) { 
    min(as.numeric(levels(n))) 
} 

facmax <- function(x) { 
    max(as.numeric(levels(x))) 
} 

hdp <- read.csv("http://www.ats.ucla.edu/stat/data/hdp.csv") 

head(hdp) 
hdp <- hdp[complete.cases(hdp),] 

hdp <- within(hdp, { 
    Married <- factor(Married, levels = 0:1, labels = c("no", "yes")) 
    DID <- factor(DID) 
    HID <- factor(HID) 
    CancerStage <- revalue(hdp$CancerStage, c("I"="1", "II"="2", "III"="3", "IV"="4")) 
}) 

Do tego czasu wszystko to zarządzanie danymi, funkcje i pakiety, których potrzebuję.

m <- glmer(remission ~ CancerStage*LengthofStay + Experience + 
      (1 | DID), data = hdp, family = binomial(link="logit")) 
summary(m) 

To jest model. To trwa chwilę i jest zbieżny z następującym ostrzeżeniem:

Warning message: 
In checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, : 
    Model failed to converge with max|grad| = 0.0417259 (tol = 0.001, component 1) 

Chociaż nie jestem pewien, czy powinienem się martwić o ostrzeżeniu, używam szacunki wykreślić średnie marginalne skutki dla interakcji interesów. Najpierw przygotowuje się zestaw danych do paszy w funkcji predict, a następnie obliczyć efektów brzegowych, jak również przedziały ufności przy użyciu stałych parametrów efektów.

Jestem przekonany, że to poprawne szacunki na skali logitowej, ale może się mylę. Tak czy inaczej, jest to działka:

plot_remission <- ggplot(newdat, aes(LengthofStay, 
    fill=factor(CancerStage), color=factor(CancerStage))) + 
    geom_ribbon(aes(ymin = plo, ymax = phi), colour=NA, alpha=0.2) + 
    geom_line(aes(y = remission), size=1.2) + 
    xlab("Length of Stay") + xlim(c(2, 10)) + 
    ylab("Probability of Remission") + ylim(c(0.0, 0.5)) + 
    labs(colour="Cancer Stage", fill="Cancer Stage") + 
    theme_minimal() 

plot_remission 

myślę teraz skala OY jest mierzona na skali logitowej ale sens to chciałbym, aby przekształcić go do przewidywanych prawdopodobieństw. Opierając się na wikipedia, coś takiego jak exp(value)/(exp(value)+1) powinno wystarczyć, aby uzyskać przewidywane prawdopodobieństwa. Chociaż mogłem zrobić newdat$remission <- exp(newdat$remission)/(exp(newdat$remission)+1) nie jestem pewien jak powinienem to zrobić dla przedziałów ufności ?.

Ostatecznie chciałbym dostać się do tej samej działki, co generuje pakiet effects. Czyli:

eff.m <- effect("CancerStage*LengthofStay", m, KR=T) 

eff.m <- as.data.frame(eff.m) 

plot_remission2 <- ggplot(eff.m, aes(LengthofStay, 
    fill=factor(CancerStage), color=factor(CancerStage))) + 
    geom_ribbon(aes(ymin = lower, ymax = upper), colour=NA, alpha=0.2) + 
    geom_line(aes(y = fit), size=1.2) + 
    xlab("Length of Stay") + xlim(c(2, 10)) + 
    ylab("Probability of Remission") + ylim(c(0.0, 0.5)) + 
    labs(colour="Cancer Stage", fill="Cancer Stage") + 
    theme_minimal() 

plot_remission2 

Choć może po prostu użyć pakietu effects, to niestety nie skompilować z wielu modeli musiałem biec do własnej pracy:

Error in model.matrix(mod2) %*% mod2$coefficients : 
    non-conformable arguments 
In addition: Warning message: 
In vcov.merMod(mod) : 
    variance-covariance matrix computed from finite-difference Hessian is 
not positive definite or contains NA values: falling back to var-cov estimated from RX 

mocowania, które wymagają dostosowania procedury szacowania, które w tej chwili chciałbym uniknąć. plus, jestem także ciekawy, co naprawdę robi tutaj. Byłbym wdzięczny za porady, jak poprawić moją początkową składnię, aby uzyskać przewidywane prawdopodobieństwa!

+1

Myślę, że twoja fabuła będzie łatwiejsza do odczytania, jeśli zrobisz coś takiego: 'ggplot (n ewdat, aes (LengthofStay, fill = factor (CancerStage), color = factor (CancerStage))) + geom_ribbon (aes (ymin = plo, ymax = phi), color = NA, alpha = 0.2) + geom_line (aes (y = remisja), rozmiar = 1,2) + xlab ("długość pobytu") + ylab ("Prawdopodobieństwo remisji") + laboratoria (kolor = "etap raka", wypełnienie = "etap raka") + temat_minimalny () ' – eipi10

+0

Powinieneś zdecydowanie martwić się ostrzeżeniem o zbieżności. –

+0

Naprawdę nie rozumiem, dlaczego tak trudno jest odpowiedzieć na pytanie ... Czy jest coś niejasnego w tym, o co proszę? – eborbath

Odpowiedz

4

Aby uzyskać podobny wynik jak funkcja effect przewidziane w swoim pytaniu, po prostu trzeba wykonać kopię przekształcać zarówno przewidywanych wartości i granice swojego przedziału ufności od skali logitowej do pierwotnej skali z przekształceniem dostarczyć: exp(x)/(1+exp(x)).

Transformacja ta może być wykonana w bazowej R z plogis funkcję:

> a <- 1:5 
> plogis(a) 
[1] 0.7310586 0.8807971 0.9525741 0.9820138 0.9933071 
> exp(a)/(1+exp(a)) 
[1] 0.7310586 0.8807971 0.9525741 0.9820138 0.9933071 

Więc za pomocą wniosek @ eipi10 użyciu wstążki dla pasm ufności zamiast liniami przerywanymi (Uważam też to prezentacja bardziej czytelne) :

ggplot(newdat, aes(LengthofStay, fill=factor(CancerStage), color=factor(CancerStage))) + 
     geom_ribbon(aes(ymin = plogis(plo), ymax = plogis(phi)), colour=NA, alpha=0.2) + 
     geom_line(aes(y = plogis(remission)), size=1.2) + 
     xlab("Length of Stay") + xlim(c(2, 10)) + 
     ylab("Probability of Remission") + ylim(c(0.0, 0.5)) + 
     labs(colour="Cancer Stage", fill="Cancer Stage") + 
     theme_minimal() 

enter image description here

wyniki są takie same (z effects_3.1-2 i lme4_1.1-13):

> compare <- merge(newdat, eff.m) 
> compare[, c("remission", "plo", "phi")] <- 
+  sapply(compare[, c("remission", "plo", "phi")], plogis) 
> head(compare) 
    CancerStage LengthofStay remission Experience  plo  phi  fit  se  lower  upper 
1   1   10 0.20657613 17.64129 0.12473504 0.3223392 0.20657613 0.3074726 0.12473625 0.3223368 
2   1   2 0.35920425 17.64129 0.27570456 0.4522040 0.35920425 0.1974744 0.27570598 0.4522022 
3   1   4 0.31636299 17.64129 0.26572506 0.3717650 0.31636299 0.1254513 0.26572595 0.3717639 
4   1   6 0.27642711 17.64129 0.22800277 0.3307300 0.27642711 0.1313108 0.22800360 0.3307290 
5   1   8 0.23976445 17.64129 0.17324422 0.3218821 0.23976445 0.2085896 0.17324530 0.3218805 
6   2   10 0.09957493 17.64129 0.06218598 0.1557113 0.09957493 0.2609519 0.06218653 0.1557101 
> compare$remission-compare$fit 
[1] 8.604228e-16 1.221245e-15 1.165734e-15 1.054712e-15 9.714451e-16 4.718448e-16 1.221245e-15 1.054712e-15 8.326673e-16 
[10] 6.383782e-16 4.163336e-16 7.494005e-16 6.383782e-16 5.689893e-16 4.857226e-16 2.567391e-16 1.075529e-16 1.318390e-16 
[19] 1.665335e-16 2.081668e-16 

Różnice między granicami ufności jest wyższa, ale wciąż bardzo mały:

> compare$plo-compare$lower 
[1] -1.208997e-06 -1.420235e-06 -8.815678e-07 -8.324261e-07 -1.076016e-06 -5.481007e-07 -1.429258e-06 -8.133438e-07 -5.648821e-07 
[10] -5.806940e-07 -5.364281e-07 -1.004792e-06 -6.314904e-07 -4.007381e-07 -4.847205e-07 -3.474783e-07 -1.398476e-07 -1.679746e-07 
[19] -1.476577e-07 -2.332091e-07 

Ale jeśli mogę użyć prawdziwego kwantyl rozkładu normalnego cmult <- qnorm(0.975) zamiast cmult <- 1.96 mogę uzyskać bardzo małe różnice także dla tych granic:

> compare$plo-compare$lower 
[1] 5.828671e-16 9.992007e-16 9.992007e-16 9.436896e-16 7.771561e-16 3.053113e-16 9.992007e-16 8.604228e-16 6.938894e-16 
[10] 5.134781e-16 2.289835e-16 4.718448e-16 4.857226e-16 4.440892e-16 3.469447e-16 1.006140e-16 3.382711e-17 6.765422e-17 
[19] 1.214306e-16 1.283695e-16 
+0

Dziękuję! To bardzo pomaga! Niestety, pomimo niewielkiej różnicy między tymi dwoma działkami, doprowadziłem je do tej samej skali, więc widać to na krzywych (dodałem "xlim" i "ylim"). Możesz także zobaczyć różnicę z np. 'porównaj <- scal (newdat, eff.m) głowa (porównaj) porównaj $ remission-compare $ fit' Rzeczywiście, w tym przykładzie różnica jest bardzo mała, ale chciałbym zrozumieć, skąd się bierze, więc Mogę to wyeliminować w moich badaniach. PS: Edytowałem działki i dodałem pakiet 'plyr'. Dzięki za odpowiedź! – eborbath

+0

Zobacz edytowaną odpowiedź. Nie mogę powtórzyć żadnej znaczącej różnicy. Może różnica w wersjach pakietów? Uwaga: powinieneś również dodać 'library (effects)' w swoim kodzie i usunąć 'ylim' swojego pierwszego wykresu (ten wykres jest w skali logitowej, więc granice 0,0,5 są poza zakresem wykresu) – Gilles

+0

dzięki za wyjaśnienie tego ! – eborbath

Powiązane problemy