線形回帰からp値とr二乗を引き出します


179

単純な線形回帰モデルから、p値(単一の説明変数の係数が非ゼロであることの有意性)とR二乗値をどのように引き出しますか?例えば...

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

p値とR二乗値がsummary(fit) 表示されることわかっていますが、これらを他の変数に固定できるようにしたいと考えています。


オブジェクトに出力を割り当てない場合(たとえば、r <- summary(lm(rnorm(10)~runif(10)))何も表示しない場合)にのみ値が表示されます。
Joshua Ulrich

回答:


157

r-squared:サマリーオブジェクトから直接r-squared値を返すことができますsummary(fit)$r.squarednames(summary(fit))直接抽出できるすべてのアイテムのリストについては、を参照してください。

モデルのp値:全体的な回帰モデルのp値を取得する場合は、 このブログ投稿で 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

1つの予測子を使用する単純回帰の場合、モデルのp値と係数のp値は同じになります。

係数のp値:複数の予測子がある場合、上記はモデルのp値を返し、係数のp値は以下を使用して抽出できます。

summary(fit)$coefficients[,4]  

または、anova(fit)上記の要約オブジェクトと同様の方法で、オブジェクトから係数のp値を取得できます。


13
直接使用するinheritsよりも、使用する方が少し良いclassです。そして多分あなたは欲しいunname(pf(f[1],f[2],f[3],lower.tail=F))ですか?
ハドリー2011

150

summary(fit)必要なすべての情報を持つオブジェクトを生成することに注意してください。beta、se、t、pの各ベクトルが格納されています。係数行列(サマリーオブジェクトに格納されている)の4番目の列を選択して、p値を取得します。

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

試してみてくださいstr(summary(fit))このオブジェクトが含まれているすべての情報を参照してください。

編集:私はここで私が与えるものに到達する方法を基本的にあなたに教えるチェイスの答えを読み違えました。


11
注:これは、切片のp値と他の予測子に簡単にアクセスできる唯一の方法です。上記の断然ベスト。
Daniel Egan

2
これが正しい答えです。一流の答えは私にはうまくいきませんでした。
Chris

8
P-Valueに簡単にアクセスしたい場合は、この回答を使用してください。要約出力自体でp値を見つけるのが少し難しいのに、なぜ複数行の関数を記述したり、新しいオブジェクト(つまりanova出力)を作成したりするのでしょうか。個々のp値自体を分離するには、ヴィンセントの回答に行番号を追加します。たとえば、次の例では、summary(fit)$coefficients[1,4] theintereccept
theforestecologist

2
注:この方法は、を使用lm()して作成されたgls()モデルでは機能しますが、モデルでは機能しません。
森林生態学者2016

3
チェイスの答えはモデルのp値を返し、この答えは係数のp値を返します。単純な回帰の場合、それらは同じですが、複数の予測子を持つモデルの場合、それらは同じではありません。したがって、どちらの回答も、何を抽出するかによって異なります。
Jeromy Anglim

44

summary()呼び出すと、によって返されたオブジェクトの構造を確認できますstr(summary(fit))。各ピースにはを使用してアクセスできます$。F統計のp値は、によって返されたオブジェクトからより簡単に取得できますanova

簡単に言うと、これを行うことができます:

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

10
これは、回帰のp値が予測子と同じである一変量回帰でのみ機能します
Bakaburg

23

上記の両方の答えは良いですが、オブジェクトの一部を抽出する手順はより一般的です。

多くの場合、関数はリストを返します。個々のコンポーネントにはstr()、コンポーネントとその名前を表示するを使用してアクセスできます。その後、$演算子を使用してそれらにアクセスできますmyobject$componentname

LMオブジェクトの場合は、1のような使用できる事前に定義されたメソッドの数があるcoef()resid()summary()などが、あなたはいつもとても幸運ではありません。


23

同様の問題に対して提案された解決策を模索しているときにこの質問に出くわしました。将来の参照のために、broomパッケージを利用するソリューションで回答の利用可能なリストを更新することは価値があると思います。

サンプルコード

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

結果

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

サイドノート

このglance関数は、キー値をきちんと要約しているので便利です。結果はとして保存され、次のdata.frame操作が簡単になります。

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

これは素晴らしい答えです!
AndrewBrēza

9

@Vincentの回答の拡張:

以下のためのlm()生成モデル:

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

以下のためのgls()生成モデル:

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

個々のp値自体を分離するには、コードに行番号を追加します。

たとえば、両方のモデルの要約で切片のp値にアクセスするには、次のようにします。

summary(fit)$coefficients[1,4]
summary(fit)$tTable[1,4]  
  • 上記の各インスタンスでは、列番号を列名に置き換えることができます。

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

サマリーテーブルstr()から値にアクセスする方法がまだわからない場合は、サマリーテーブルの構造を理解するために使用します。

str(summary(fit))

7

これは、p値を取得する最も簡単な方法です。

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

1
この方法を試しましたが、線形モデルにNA項が含まれていると失敗します
j_v_wow_d

5

このlmp関数を何度も使用しました。

そして、ある時点で、データ分析を強化するために新しい機能を追加することにしました。私はRや統計の専門家ではありませんが、人々は通常、線形回帰のさまざまな情報を見ています。

  • p値
  • aとb
  • そしてもちろん、ポイント分布の側面

例を挙げましょう。あなたはここにいます

以下は、さまざまな変数を使用した再現可能な例です。

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)

この関数よりも確かに高速な解決策がありますが、機能します。


2

の最後に表示される最後のp値について、summary()関数はpf()を使用してsummary(fit)$fstatistic値から計算します。

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

出典:[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
このコードが機能する理由について、たとえたとえ短いとしても、説明を提供してください。
aribeiro 2016年

これは既存の回答(特に承認された回答)をどのように改善しますか?
Ben Bolker 2016年

0

別のオプションは、lmの代わりにcor.test関数を使用することです。

> 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

使用する:

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

ここnumで、は、係数行列の行を示す数値です。これは、モデルにある特徴の数と、p値を取得する特徴によって異なります。たとえば、変数が1つしかない場合、切片のp値は[1,4]になり、実際の変数の次のp値は[2,4]になります。だからあなたnumは2になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.