Ziehen Sie die p-Werte und das r-Quadrat aus einer linearen Regression heraus

179

Wie ziehen Sie den p-Wert (für die Signifikanz des Koeffizienten der einzelnen erklärenden Variablen ungleich Null) und den R-Quadrat-Wert aus einem einfachen linearen Regressionsmodell heraus? Beispielsweise...

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

Ich weiß, dass der p-Wert und der R-Quadrat-Wert summary(fit) angezeigt werden, aber ich möchte diese in andere Variablen einfügen können.

grautur
quelle
Die Werte werden nur angezeigt, wenn Sie die Ausgabe keinem Objekt zuweisen (z. B. r <- summary(lm(rnorm(10)~runif(10)))nichts anzeigen).
Joshua Ulrich

Antworten:

157

r-Quadrat : Sie können den r-Quadrat-Wert direkt vom Zusammenfassungsobjekt zurückgeben summary(fit)$r.squared. Siehe names(summary(fit))für eine Liste aller Artikel , die Sie direkt extrahieren.

Modell-p-Wert: Wenn Sie den p-Wert des gesamten Regressionsmodells erhalten möchten, beschreibt dieser Blog-Beitrag eine Funktion zum Zurückgeben des p-Werts:

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

Bei einer einfachen Regression mit einem Prädiktor sind der p-Wert des Modells und der p-Wert für den Koeffizienten gleich.

Koeffizienten-p-Werte: Wenn Sie mehr als einen Prädiktor haben, gibt der obige den p-Wert des Modells zurück, und der p-Wert für Koeffizienten kann extrahiert werden mit:

summary(fit)$coefficients[,4]  

Alternativ können Sie den p-Wert von Koeffizienten aus dem anova(fit)Objekt auf ähnliche Weise wie das obige Zusammenfassungsobjekt abrufen.

Verfolgungsjagd
quelle
13
Es ist ein bisschen besser zu verwenden inheritsals classdirekt. Und vielleicht willst du unname(pf(f[1],f[2],f[3],lower.tail=F))?
Hadley
150

Beachten Sie, dass summary(fit)ein Objekt mit allen benötigten Informationen generiert wird. Darin sind die Beta-, Se-, T- und P-Vektoren gespeichert. Erhalten Sie die p-Werte, indem Sie die 4. Spalte der Koeffizientenmatrix auswählen (im Zusammenfassungsobjekt gespeichert):

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

Versuchen Sie str(summary(fit)), alle Informationen zu sehen, die dieses Objekt enthält.

Bearbeiten: Ich hatte Chases Antwort falsch verstanden, die Ihnen im Grunde sagt, wie Sie zu dem kommen, was ich hier gebe.

Vincent
quelle
11
Hinweis: Dies ist die einzige Methode, mit der Sie leicht auf den p-Wert des Abschnitts sowie auf die anderen Prädiktoren zugreifen können. Bei weitem das Beste von oben.
Daniel Egan
2
Dies ist die richtige Antwort. Die bestbewertete Antwort hat bei mir NICHT funktioniert.
Chris
8
WENN SIE EINFACHEN ZUGRIFF AUF P-VALUE WOLLEN, VERWENDEN SIE DIESE ANTWORT. Warum sollten Sie mehrzeilige Funktionen schreiben oder neue Objekte erstellen (z. B. Anova-Ausgaben), wenn Sie nur etwas genauer hinschauen müssen, um den p-Wert in der Zusammenfassungsausgabe selbst zu finden? Zur Isolierung eines einzelnen p-Wert selbst, würden Sie eine Zeilennummer zu Vincent Antwort hinzufügen: zum Beispiel summary(fit)$coefficients[1,4] für thei ntercept
theforestecologist
2
Hinweis: Diese Methode funktioniert für Modelle, die mit erstellt wurden lm(), funktioniert jedoch nicht für gls()Modelle.
Theforestecologist
3
Die Antwort von Chase gibt den p-Wert des Modells zurück. Diese Antwort gibt den p-Wert der Koeffizienten zurück. Im Falle einer einfachen Regression sind sie gleich, aber im Fall eines Modells mit mehreren Prädiktoren sind sie nicht gleich. Daher sind beide Antworten nützlich, je nachdem, was Sie extrahieren möchten.
Jeromy Anglim
44

Sie können die Struktur des von zurückgegebenen Objekts summary()durch Aufrufen sehen str(summary(fit)). Auf jedes Stück kann mit zugegriffen werden $. Der p-Wert für die F-Statistik lässt sich leichter aus dem von zurückgegebenen Objekt ermitteln anova.

Kurz gesagt, Sie können dies tun:

rSquared <- summary(fit)$r.squared
pVal <- anova(fit)$'Pr(>F)'[1]
jberg
quelle
10
Dies funktioniert nur für univariate Regressionen, bei denen der p-Wert der Regression der gleiche ist wie der Prädiktor
Bakaburg
23

Während beide obigen Antworten gut sind, ist das Verfahren zum Extrahieren von Teilen von Objekten allgemeiner.

In vielen Fällen geben Funktionen Listen zurück, und auf die einzelnen Komponenten kann zugegriffen werden, str()wodurch die Komponenten zusammen mit ihren Namen gedruckt werden. Sie können dann mit dem Operator $ darauf zugreifen, d myobject$componentname. H.

Im Fall von lm Objekten gibt es eine Reihe von vordefinierten Methoden kann man wie verwenden coef(), resid(), summary()etc, aber Sie werden nicht immer so viel Glück.

richiemorrisroe
quelle
23

Ich bin auf diese Frage gestoßen, als ich nach Lösungsvorschlägen für ein ähnliches Problem gesucht habe. Ich gehe davon aus, dass es sich zum späteren Nachschlagen lohnen kann, die verfügbare Antwortliste mit einer Lösung zu aktualisieren, die das broomPaket verwendet.

Beispielcode

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

Ergebnisse

>> 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

Randnotizen

Ich finde die glanceFunktion nützlich, da sie die Schlüsselwerte übersichtlich zusammenfasst. Die Ergebnisse werden als gespeichert, data.framewas die weitere Manipulation erleichtert:

>> class(glance(fit))
[1] "data.frame"
Konrad
quelle
Das ist eine großartige Antwort!
Andrew Brēza
9

Erweiterung der Antwort von @Vincent :

Für lm()generierte Modelle:

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

Für gls()generierte Modelle:

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

Um einen einzelnen p-Wert selbst zu isolieren, fügen Sie dem Code eine Zeilennummer hinzu:

So greifen Sie beispielsweise auf den p-Wert des Abschnitts in beiden Modellzusammenfassungen zu:

summary(fit)$coefficients[1,4]
summary(fit)$tTable[1,4]  
  • Beachten Sie, dass Sie die Spaltennummer in jeder der oben genannten Instanzen durch den Spaltennamen ersetzen können:

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

Wenn Sie sich immer noch nicht sicher sind, wie Sie auf einen Wert aus der Übersichtstabelle zugreifen sollen, verwenden Sie diese str(), um die Struktur der Übersichtstabelle zu ermitteln:

str(summary(fit))
der Waldökologe
quelle
7

Dies ist der einfachste Weg, um die p-Werte zu ziehen:

coef(summary(modelname))[, "Pr(>|t|)"]
RTrain3k
quelle
1
Ich habe diese Methode ausprobiert, aber sie
schlägt
5

Ich habe diese lmp-Funktion ziemlich oft benutzt.

Und irgendwann habe ich beschlossen, neue Funktionen hinzuzufügen, um die Datenanalyse zu verbessern. Ich bin kein Experte für R oder Statistik, aber die Leute betrachten normalerweise verschiedene Informationen einer linearen Regression:

  • p-Wert
  • A und B
  • und natürlich den Aspekt der Punktverteilung

Lassen Sie uns ein Beispiel haben. Du hast hier

Hier ein reproduzierbares Beispiel mit verschiedenen Variablen:

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)

Es gibt sicherlich eine schnellere Lösung als diese Funktion, aber sie funktioniert.

Dorian Grv
quelle
2

Für den am Ende angezeigten endgültigen p-Wert berechnet summary()die Funktion pf()aus den summary(fit)$fstatisticWerten.

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

Quelle: [1] , [2]

Saftever
quelle
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
Jojo
quelle
1
Möchten Sie, wenn auch nur kurz, erklären, warum dieser Code funktioniert?
Aribeiro
Wie verbessert sich dies gegenüber den vorhandenen Antworten (und insbesondere der akzeptierten Antwort)?
Ben Bolker
0

Eine andere Option ist die Verwendung der Funktion cor.test anstelle von 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
dalloliogm
quelle
0

Verwenden:

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

Dabei numist eine Zahl angegeben, die die Zeile der Koeffizientenmatrix bezeichnet. Dies hängt davon ab, wie viele Funktionen Ihr Modell enthält und für welche Sie den p-Wert herausziehen möchten. Wenn Sie beispielsweise nur eine Variable haben, gibt es einen p-Wert für den Achsenabschnitt, der [1,4] ist, und den nächsten für Ihre tatsächliche Variable, der [2,4] ist. Also wirst numdu 2 sein.

Tirtha
quelle