wyciągnąć wartości p i r-kwadrat z regresji liniowej


179

Jak wyciągnąć wartość p (dla istotności współczynnika pojedynczej zmiennej objaśniającej niezerowej) i wartość R-kwadrat z prostego modelu regresji liniowej? Na przykład...

x = cumsum(c(0, runif(100, -1, +1)))
y = cumsum(c(0, runif(100, -1, +1)))
fit = lm(y ~ x)
summary(fit)

Wiem, że summary(fit) wyświetla wartość p i wartość R-kwadrat, ale chcę móc umieścić je w innych zmiennych.


Wyświetla wartości tylko wtedy, gdy nie przypiszesz wyjścia do obiektu (np. r <- summary(lm(rnorm(10)~runif(10)))Nic nie wyświetla).
Joshua Ulrich

Odpowiedzi:


157

r-kwadrat : Możesz zwrócić wartość r-kwadrat bezpośrednio z obiektu podsumowania summary(fit)$r.squared. Zobacz names(summary(fit))listę wszystkich elementów, które możesz wyodrębnić bezpośrednio.

Modelowa wartość p: Jeśli chcesz uzyskać wartość p ogólnego modelu regresji, ten post na blogu przedstawia w zarysie funkcję zwracającą wartość p:

lmp <- function (modelobject) {
    if (class(modelobject) != "lm") stop("Not an object of class 'lm' ")
    f <- summary(modelobject)$fstatistic
    p <- pf(f[1],f[2],f[3],lower.tail=F)
    attributes(p) <- NULL
    return(p)
}

> lmp(fit)
[1] 1.622665e-05

W przypadku prostej regresji z jednym predyktorem wartość p modelu i wartość p dla współczynnika będą takie same.

Współczynnik wartości p: Jeśli masz więcej niż jeden predyktor, powyższe zwróci wartość p modelu, a wartość p dla współczynników można wyodrębnić za pomocą:

summary(fit)$coefficients[,4]  

Alternatywnie możesz pobrać wartość p współczynników z anova(fit)obiektu w podobny sposób, jak w przypadku obiektu podsumowania powyżej.


13
Trochę lepiej jest używać inheritsniż classbezpośrednio. A może chcesz unname(pf(f[1],f[2],f[3],lower.tail=F))?
Hadley

150

Zwróć uwagę, że summary(fit)generuje obiekt ze wszystkimi potrzebnymi informacjami. Wektory beta, se, t i p są w nim przechowywane. Uzyskaj wartości p, wybierając czwartą kolumnę macierzy współczynników (przechowywaną w obiekcie podsumowania):

summary(fit)$coefficients[,4] 
summary(fit)$r.squared

Spróbuj str(summary(fit))zobaczyć wszystkie informacje, które zawiera ten obiekt.

Edycja: źle odczytałem odpowiedź Chase, która w zasadzie mówi ci, jak dostać się do tego, co tutaj podaję.


11
Uwaga: jest to jedyna metoda, która zapewnia łatwy dostęp do wartości p punktu przecięcia z osią, a także innych predyktorów. Zdecydowanie najlepsze z powyższych.
Daniel Egan,

2
To jest właściwa odpowiedź. Najwyżej oceniana odpowiedź NIE działa dla mnie.
Chris,

8
JEŚLI CHCESZ ŁATWEGO DOSTĘPU DO WARTOŚCI P, SKORZYSTAJ Z TEJ ODPOWIEDZI. Dlaczego miałbyś przechodzić przez pisanie funkcji wielowierszowych lub tworzenie nowych obiektów (np. Wyjścia anova), skoro wystarczy spojrzeć nieco dokładniej, aby znaleźć wartość p w samym podsumowaniu wyników. Aby wyodrębnić samą indywidualną wartość p, należy dodać numer wiersza do odpowiedzi Vincenta: na przykład summary(fit)$coefficients[1,4] dla terceptu
leśnika

2
Uwaga: ta metoda działa w przypadku modeli utworzonych za pomocą, lm()ale nie działa w przypadku gls()modeli.
leśnik,

3
Odpowiedź Chase'a zwraca wartość p modelu, ta odpowiedź zwraca wartość p współczynników. W przypadku prostej regresji są takie same, ale w przypadku modelu z wieloma predyktorami nie są takie same. Dlatego obie odpowiedzi są przydatne w zależności od tego, co chcesz wyodrębnić.
Jeromy Anglim

44

Możesz zobaczyć strukturę obiektu zwróconego summary()przez wywołanie str(summary(fit)). Dostęp do każdego elementu można uzyskać za pomocą $. Wartość p dla statystyki F jest łatwiejsza do uzyskania z obiektu zwróconego przez anova.

Dokładniej, możesz to zrobić:

rSquared <- summary(fit)$r.squared
pVal <- anova(fit)$'Pr(>F)'[1]

10
działa to tylko dla regresji jednowymiarowych, gdzie wartość regresji jest taka sama jak predyktora
Bakaburg,

23

Chociaż obie powyższe odpowiedzi są dobre, procedura wyodrębniania części obiektów jest bardziej ogólna.

W wielu przypadkach funkcje zwracają listy, a dostęp do poszczególnych składników można uzyskać za pomocą polecenia, str()które wypisze składniki wraz z ich nazwami. Możesz wtedy uzyskać do nich dostęp za pomocą operatora $, tj myobject$componentname.

W przypadku obiektów lm, istnieje szereg predefiniowanych metod można użyć takich jak coef(), resid(), summary()itp, ale nie zawsze będzie tak szczęśliwy.


23

Natknąłem się na to pytanie, badając sugerowane rozwiązania podobnego problemu; Przypuszczam, że w przyszłości warto zaktualizować dostępną listę odpowiedzi rozwiązaniem wykorzystującym rozszerzeniebroom pakiet.

Przykładowy kod

x = cumsum(c(0, runif(100, -1, +1)))
y = cumsum(c(0, runif(100, -1, +1)))
fit = lm(y ~ x)
require(broom)
glance(fit)

Wyniki

>> glance(fit)
  r.squared adj.r.squared    sigma statistic    p.value df    logLik      AIC      BIC deviance df.residual
1 0.5442762     0.5396729 1.502943  118.2368 1.3719e-18  2 -183.4527 372.9055 380.7508 223.6251          99

Dodatkowe uwagi

Uważam, że glancefunkcja jest przydatna, ponieważ starannie podsumowuje kluczowe wartości. Wyniki są przechowywane jako a, data.frameco ułatwia dalszą manipulację:

>> class(glance(fit))
[1] "data.frame"

To świetna odpowiedź!
Andrew Brēza

9

Rozszerzenie @Vincent „s odpowiedź :

Dla lm()wygenerowanych modeli:

summary(fit)$coefficients[,4]   ##P-values 
summary(fit)$r.squared          ##R squared values

Dla gls()wygenerowanych modeli:

summary(fit)$tTable[,4]         ##P-values
##R-squared values are not generated b/c gls uses max-likelihood not Sums of Squares

Aby wyodrębnić samą indywidualną wartość p, należy dodać numer wiersza do kodu:

Na przykład, aby uzyskać dostęp do wartości p punktu przecięcia z osią w obu podsumowaniach modelu:

summary(fit)$coefficients[1,4]
summary(fit)$tTable[1,4]  
  • Uwaga, możesz zastąpić numer kolumny nazwą kolumny w każdym z powyższych wystąpień:

    summary(fit)$coefficients[1,"Pr(>|t|)"]  ##lm 
    summary(fit)$tTable[1,"p-value"]         ##gls 

Jeśli nadal nie masz pewności, jak uzyskać dostęp do wartości z tabeli podsumowań, której użyjesz str()do ustalenia struktury tabeli podsumowań:

str(summary(fit))

7

Oto najłatwiejszy sposób na pobranie wartości p:

coef(summary(modelname))[, "Pr(>|t|)"]

1
Wypróbowałem tę metodę, ale zakończy się niepowodzeniem, jeśli model liniowy zawiera jakiekolwiek warunki NA
j_v_wow_d,

5

Używałem tej funkcji lmp dość dużo razy.

W pewnym momencie zdecydowałem się dodać nowe funkcje, aby ulepszyć analizę danych. Nie jestem ekspertem w R ani statystykach, ale ludzie zwykle patrzą na różne informacje dotyczące regresji liniowej:

  • wartość p
  • a i b
  • i oczywiście aspekt dystrybucji punktów

Weźmy przykład. Masz tutaj

Tutaj odtwarzalny przykład z różnymi zmiennymi:

Ex<-structure(list(X1 = c(-36.8598, -37.1726, -36.4343, -36.8644, 
-37.0599, -34.8818, -31.9907, -37.8304, -34.3367, -31.2984, -33.5731
), X2 = c(64.26, 63.085, 66.36, 61.08, 61.57, 65.04, 72.69, 63.83, 
67.555, 76.06, 68.61), Y1 = c(493.81544, 493.81544, 494.54173, 
494.61364, 494.61381, 494.38717, 494.64122, 493.73265, 494.04246, 
494.92989, 494.98384), Y2 = c(489.704166, 489.704166, 490.710962, 
490.653212, 490.710612, 489.822928, 488.160904, 489.747776, 490.600579, 
488.946738, 490.398958), Y3 = c(-19L, -19L, -19L, -23L, -30L, 
-43L, -43L, -2L, -58L, -47L, -61L)), .Names = c("X1", "X2", "Y1", 
"Y2", "Y3"), row.names = c(NA, 11L), class = "data.frame")


library(reshape2)
library(ggplot2)
Ex2<-melt(Ex,id=c("X1","X2"))
colnames(Ex2)[3:4]<-c("Y","Yvalue")
Ex3<-melt(Ex2,id=c("Y","Yvalue"))
colnames(Ex3)[3:4]<-c("X","Xvalue")

ggplot(Ex3,aes(Xvalue,Yvalue))+
          geom_smooth(method="lm",alpha=0.2,size=1,color="grey")+
          geom_point(size=2)+
          facet_grid(Y~X,scales='free')


#Use the lmp function

lmp <- function (modelobject) {
  if (class(modelobject) != "lm") stop("Not an object of class 'lm' ")
  f <- summary(modelobject)$fstatistic
    p <- pf(f[1],f[2],f[3],lower.tail=F)
    attributes(p) <- NULL
    return(p)
    }

# create function to extract different informations from lm

lmtable<-function (var1,var2,data,signi=NULL){
  #var1= y data : colnames of data as.character, so "Y1" or c("Y1","Y2") for example
  #var2= x data : colnames of data as.character, so "X1" or c("X1","X2") for example
  #data= data in dataframe, variables in columns
  # if signi TRUE, round p-value with 2 digits and add *** if <0.001, ** if < 0.01, * if < 0.05.

  if (class(data) != "data.frame") stop("Not an object of class 'data.frame' ")
  Tabtemp<-data.frame(matrix(NA,ncol=6,nrow=length(var1)*length(var2)))
  for (i in 1:length(var2))
       {
  Tabtemp[((length(var1)*i)-(length(var1)-1)):(length(var1)*i),1]<-var1
  Tabtemp[((length(var1)*i)-(length(var1)-1)):(length(var1)*i),2]<-var2[i]
  colnames(Tabtemp)<-c("Var.y","Var.x","p-value","a","b","r^2")

  for (n in 1:length(var1))
  {
  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),3]<-lmp(lm(data[,var1[n]]~data[,var2[i]],data))

  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),4]<-coef(lm(data[,var1[n]]~data[,var2[i]],data))[1]

  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),5]<-coef(lm(data[,var1[n]]~data[,var2[i]],data))[2]

  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),6]<-summary(lm(data[,var1[n]]~data[,var2[i]],data))$r.squared
  }
  }

  signi2<-data.frame(matrix(NA,ncol=3,nrow=nrow(Tabtemp)))
  signi2[,1]<-ifelse(Tabtemp[,3]<0.001,paste0("***"),ifelse(Tabtemp[,3]<0.01,paste0("**"),ifelse(Tabtemp[,3]<0.05,paste0("*"),paste0(""))))
  signi2[,2]<-round(Tabtemp[,3],2)
  signi2[,3]<-paste0(format(signi2[,2],digits=2),signi2[,1])

  for (l in 1:nrow(Tabtemp))
    {
  Tabtemp$"p-value"[l]<-ifelse(is.null(signi),
         Tabtemp$"p-value"[l],
         ifelse(isTRUE(signi),
                paste0(signi2[,3][l]),
                Tabtemp$"p-value"[l]))
  }

   Tabtemp
}

# ------- EXAMPLES ------

lmtable("Y1","X1",Ex)
lmtable(c("Y1","Y2","Y3"),c("X1","X2"),Ex)
lmtable(c("Y1","Y2","Y3"),c("X1","X2"),Ex,signi=TRUE)

Na pewno jest szybsze rozwiązanie niż ta funkcja, ale działa.


2

Dla końcowej wartości p wyświetlanej na końcu summary(), funkcja używa pf()do obliczenia na podstawie summary(fit)$fstatisticwartości.

fstat <- summary(fit)$fstatistic
pf(fstat[1], fstat[2], fstat[3], lower.tail=FALSE)

Źródło: [1] , [2]


1
x = cumsum(c(0, runif(100, -1, +1)))
y = cumsum(c(0, runif(100, -1, +1)))
fit = lm(y ~ x)
> names(summary(fit))
[1] "call"          "terms"        
 [3] "residuals"     "coefficients" 
 [5] "aliased"       "sigma"        
 [7] "df"            "r.squared"    
 [9] "adj.r.squared" "fstatistic"   
[11] "cov.unscaled" 
    summary(fit)$r.squared

1
Zadbaj o wyjaśnienie, choćby zwięzłe, dlaczego ten kod działa?
aribeiro

jak to wpływa na istniejące odpowiedzi (aw szczególności zaakceptowaną odpowiedź)?
Ben Bolker

0

Inną opcją jest użycie funkcji cor.test zamiast lm:

> x <- c(44.4, 45.9, 41.9, 53.3, 44.7, 44.1, 50.7, 45.2, 60.1)
> y <- c( 2.6,  3.1,  2.5,  5.0,  3.6,  4.0,  5.2,  2.8,  3.8)

> mycor = cor.test(x,y)
> mylm = lm(x~y)

# r and rsquared:
> cor.test(x,y)$estimate ** 2
      cor 
0.3262484 
> summary(lm(x~y))$r.squared
[1] 0.3262484

# P.value 

> lmp(lm(x~y))  # Using the lmp function defined in Chase's answer
[1] 0.1081731
> cor.test(x,y)$p.value
[1] 0.1081731

0

Posługiwać się:

(summary(fit))$coefficients[***num***,4]

gdzie numjest liczbą oznaczającą wiersz macierzy współczynników. Będzie to zależeć od tego, ile funkcji masz w swoim modelu i dla której chcesz uzyskać wartość p. Na przykład, jeśli masz tylko jedną zmienną, będzie jedna wartość p dla punktu przecięcia z osią, która będzie wynosić [1,4], a następna dla zmiennej rzeczywistej, która będzie wynosić [2,4]. Więc twoja numwola będzie 2.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.