retire os valores de p e r ao quadrado de uma regressão linear


179

Como você extrai o valor-p (para o significado do coeficiente da variável explicativa única ser diferente de zero) e o valor do quadrado-R de um modelo de regressão linear simples? Por exemplo...

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

Eu sei que summary(fit) exibe o valor de p e o valor de R ao quadrado, mas quero poder colá-los em outras variáveis.


Ele exibe apenas os valores se você não atribuir a saída a um objeto (por exemplo r <- summary(lm(rnorm(10)~runif(10))), não exibe nada).
21711 Joshua Ulrich

Respostas:


157

quadrado ao r : você pode retornar o valor ao quadrado r diretamente do objeto de resumo summary(fit)$r.squared. Veja names(summary(fit))uma lista de todos os itens que você pode extrair diretamente.

Valor p do modelo: se você deseja obter o valor p do modelo de regressão geral, esta postagem do blog descreve uma função para retornar o valor 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

No caso de uma regressão simples com um preditor, o valor p do modelo e o valor p do coeficiente serão os mesmos.

Valores p do coeficiente: se você tiver mais de um preditor, o valor acima retornará o valor p do modelo, e o valor p dos coeficientes pode ser extraído usando:

summary(fit)$coefficients[,4]  

Como alternativa, você pode obter o valor-p dos coeficientes do anova(fit)objeto de maneira semelhante ao objeto de resumo acima.


13
É um pouco melhor usar inheritsdo que classdiretamente. E talvez você queira unname(pf(f[1],f[2],f[3],lower.tail=F))?
Hadley

150

Observe que summary(fit)gera um objeto com todas as informações necessárias. Os vetores beta, se, t e p são armazenados nele. Obtenha os valores p selecionando a quarta coluna da matriz de coeficientes (armazenada no objeto de resumo):

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

Tente str(summary(fit))ver todas as informações que esse objeto contém.

Edit: Eu tinha interpretado mal a resposta de Chase, que basicamente diz como chegar ao que eu dou aqui.


11
Nota: este é o único método que fornece acesso fácil ao valor-p da interceptação, bem como aos outros preditores. De longe o melhor de acima.
Daniel Egan

2
Esta é a resposta certa. A resposta mais bem avaliada NÃO funcionou para mim.
Chris

8
SE VOCÊ QUER ACESSO FÁCIL AO VALOR P, USE ESTA RESPOSTA. Por que você passaria escrevendo funções de várias linhas ou criando novos objetos (ou seja, saídas anova), quando você só precisa procurar um pouco mais para encontrar o valor p na saída do resumo em si. Para isolar um próprio p-valor individual, você adicionar um número de linha para a resposta de Vincent: por exemplo, summary(fit)$coefficients[1,4] para thei ntercept
theforestecologist

2
Nota: esse método funciona para modelos criados usando, lm()mas não para gls()modelos.
Theforestecologist

3
A resposta de Chase retorna o valor-p do modelo, essa resposta retorna o valor-p dos coeficientes. No caso de uma regressão simples, eles são iguais, mas no caso de um modelo com múltiplos preditores, eles não são os mesmos. Assim, as duas respostas são úteis, dependendo do que você deseja extrair.
precisa

44

Você pode ver a estrutura do objeto retornado summary()chamando str(summary(fit)). Cada peça pode ser acessada usando $. O valor de p para a estatística F é mais facilmente obtido do objeto retornado por anova.

Concisa, você pode fazer isso:

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

10
Isso só funciona para regressões univariadas onde o p val da regressão é o mesmo do preditor
Bakaburg

23

Embora as duas respostas acima sejam boas, o procedimento para extrair partes de objetos é mais geral.

Em muitos casos, as funções retornam listas e os componentes individuais podem ser acessados ​​usando o str()que imprimirá os componentes junto com seus nomes. Você pode acessá-los usando o operador $, ou seja myobject$componentname.

No caso de objetos lm, há uma série de métodos predefinidos pode-se usar tais como coef(), resid(), summary()etc, mas não será sempre a mesma sorte.


23

Me deparei com essa pergunta enquanto explorava soluções sugeridas para um problema semelhante; Presumo que, para referência futura, talvez valha a pena atualizar a lista de respostas disponível com uma solução utilizando o broompacote.

Código de amostra

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

Resultados

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

Notas laterais

Acho que a glancefunção é útil, pois resume claramente os valores-chave. Os resultados são armazenados como um data.frameque facilita a manipulação adicional:

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

Esta é uma ótima resposta!
Andrew Brēza 23/04

9

Extensão de 's @Vincent resposta :

Para lm()modelos gerados:

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

Para gls()modelos gerados:

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

Para isolar um valor-p individual, adicione um número de linha ao código:

Por exemplo, para acessar o valor-p da interceptação nos dois resumos do modelo:

summary(fit)$coefficients[1,4]
summary(fit)$tTable[1,4]  
  • Observe que você pode substituir o número da coluna pelo nome da coluna em cada uma das instâncias acima:

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

Se você ainda não tiver certeza de como acessar um valor, use str()a tabela de resumo para descobrir a estrutura da tabela de resumo:

str(summary(fit))

7

Esta é a maneira mais fácil de obter os valores-p:

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

1
Eu tentei esse método, mas ele falhará se o modelo linear contiver algum termo de NA
j_v_wow_d 25/12/16

5

Eu usei essa função lmp várias vezes.

E, a certa altura, decidi adicionar novos recursos para aprimorar a análise de dados. Não sou especialista em R ou estatística, mas as pessoas geralmente procuram informações diferentes de uma regressão linear:

  • valor p
  • aeb
  • e, claro, o aspecto da distribuição de pontos

Vamos dar um exemplo. Você tem aqui

Aqui está um exemplo reproduzível com diferentes variáveis:

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)

Certamente, existe uma solução mais rápida que essa função, mas ela funciona.


2

Para o valor p final exibido no final de summary(), a função usa pf()para calcular a partir dos summary(fit)$fstatisticvalores.

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

Fonte: [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
Gostaria de fornecer uma explicação, mesmo que brevemente, sobre por que esse código funciona?
Aribeiro 26/03

como isso melhora as respostas existentes (e em particular a resposta aceita)?
Ben Bolker 26/03

0

Outra opção é usar a função cor.test, em vez de 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

Usar:

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

onde numé um número que indica a linha da matriz de coeficientes. Depende de quantos recursos você possui no seu modelo e para qual você deseja obter o valor p. Por exemplo, se você tiver apenas uma variável, haverá um valor p para a interceptação que será [1,4] e o próximo para sua variável real, que será [2,4]. Então você numserá 2.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.