lấy ra các giá trị p và r bình phương từ hồi quy tuyến tính


179

Làm thế nào để bạn rút ra giá trị p (cho tầm quan trọng của hệ số của biến giải thích duy nhất là khác không) và giá trị bình phương R từ mô hình hồi quy tuyến tính đơn giản? Ví dụ...

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

Tôi biết rằng summary(fit) hiển thị giá trị p và giá trị R bình phương, nhưng tôi muốn có thể gắn chúng vào các biến khác.


Nó chỉ hiển thị các giá trị nếu bạn không gán đầu ra cho một đối tượng (ví dụ: r <- summary(lm(rnorm(10)~runif(10)))không hiển thị bất cứ thứ gì).
Joshua Ulrich

Câu trả lời:


157

r-squared : Bạn có thể trả về giá trị r bình phương trực tiếp từ đối tượng tóm tắt summary(fit)$r.squared. Xem names(summary(fit))để biết danh sách tất cả các mục bạn có thể trích xuất trực tiếp.

Mô hình p-value: Nếu bạn muốn lấy giá trị p của mô hình hồi quy tổng thể, bài đăng trên blog này phác thảo một hàm để trả về giá trị 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

Trong trường hợp hồi quy đơn giản với một yếu tố dự đoán, giá trị p mô hình và giá trị p cho hệ số sẽ giống nhau.

Giá trị p hệ số: Nếu bạn có nhiều hơn một yếu tố dự đoán, thì ở trên sẽ trả về giá trị p của mô hình và giá trị p cho các hệ số có thể được trích xuất bằng cách sử dụng:

summary(fit)$coefficients[,4]  

Ngoài ra, bạn có thể lấy giá trị p của các hệ số từ anova(fit)đối tượng theo cách tương tự với đối tượng tóm tắt ở trên.


13
Nó tốt hơn một chút để sử dụng inheritshơn là classtrực tiếp. Và có thể bạn muốn unname(pf(f[1],f[2],f[3],lower.tail=F))?
hadley

150

Lưu ý rằng summary(fit)tạo ra một đối tượng với tất cả các thông tin bạn cần. Các vectơ beta, se, t và p được lưu trữ trong đó. Lấy các giá trị p bằng cách chọn cột thứ 4 của ma trận hệ số (được lưu trong đối tượng tóm tắt):

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

Hãy thử str(summary(fit))xem tất cả các thông tin mà đối tượng này chứa.

Chỉnh sửa: Tôi đã đọc sai câu trả lời của Chase, về cơ bản cho bạn biết làm thế nào để đến với những gì tôi đưa ra ở đây.


11
Lưu ý: đây là phương pháp duy nhất giúp bạn dễ dàng truy cập vào giá trị p của phần chặn cũng như các yếu tố dự đoán khác. Cho đến nay tốt nhất ở trên.
Daniel Egan

2
Đây là câu trả lời đúng. Câu trả lời hàng đầu KHÔNG làm việc cho tôi.
Chris

8
NẾU BẠN MUỐN TIẾP CẬN DỄ DÀNG ĐẾN P-VALUE, SỬ DỤNG TRẢ LỜI NÀY. Tại sao bạn lại phải viết các hàm đa dòng hoặc tạo các đối tượng mới (nghĩa là đầu ra anova), khi bạn chỉ cần tìm một chút khó khăn hơn để tìm giá trị p trong chính đầu ra tóm tắt. Để tự cô lập một giá trị p riêng lẻ, bạn sẽ thêm một số hàng vào câu trả lời của Vincent: ví dụ: summary(fit)$coefficients[1,4] đối với người nhận
bác sĩ lâm sàng

2
Lưu ý: phương pháp này hoạt động cho các mô hình được tạo bằng cách sử dụng lm()nhưng không hoạt động cho gls()các mô hình.
bác sĩ lâm sàng

3
Câu trả lời của Chase trả về giá trị p của mô hình, câu trả lời này trả về giá trị p của các hệ số. Trong trường hợp hồi quy đơn giản, chúng giống nhau, nhưng trong trường hợp mô hình có nhiều yếu tố dự đoán, chúng không giống nhau. Vì vậy, cả hai câu trả lời đều hữu ích tùy thuộc vào những gì bạn muốn trích xuất.
Jeromy Anglim

44

Bạn có thể thấy cấu trúc của đối tượng được trả về bằng summary()cách gọi str(summary(fit)). Mỗi mảnh có thể được truy cập bằng cách sử dụng $. Giá trị p cho thống kê F dễ dàng có hơn từ đối tượng được trả về anova.

Chính xác, bạn có thể làm điều này:

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

10
điều này chỉ hoạt động đối với các hồi quy đơn biến trong đó p val của hồi quy là giống nhau của công cụ dự đoán
Bakaburg

23

Trong khi cả hai câu trả lời ở trên đều tốt, quy trình trích xuất các phần của đối tượng thì tổng quát hơn.

Trong nhiều trường hợp, các hàm trả về danh sách và các thành phần riêng lẻ có thể được truy cập bằng cách sử dụng str()sẽ in các thành phần cùng với tên của chúng. Sau đó, bạn có thể truy cập chúng bằng toán tử $, nghĩa là myobject$componentname.

Trong trường hợp của các đối tượng lm, có một số phương pháp xác định trước người ta có thể sử dụng như coef(), resid(), summary()vv, nhưng bạn sẽ phải lúc nào cũng được may mắn như vậy.


23

Tôi đã gặp câu hỏi này trong khi khám phá các giải pháp được đề xuất cho một vấn đề tương tự; Tôi cho rằng để tham khảo trong tương lai có thể đáng để cập nhật danh sách câu trả lời có sẵn với một giải pháp sử dụng broomgói.

Mã mẫu

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

Các kết quả

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

Ghi chú bên

Tôi thấy glancehàm này rất hữu ích vì nó tóm tắt gọn gàng các giá trị chính. Các kết quả được lưu trữ dưới dạng data.framegiúp thao tác dễ dàng hơn:

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

Đây là một câu trả lời tuyệt vời!
Andrew Brēza

9

Gia hạn câu trả lời của @Vincent :

Đối với lm()các mô hình được tạo:

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

Đối với gls()các mô hình được tạo:

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

Để tự cô lập một giá trị p riêng lẻ, bạn sẽ thêm một số hàng vào mã:

Ví dụ: để truy cập giá trị p của phần chặn trong cả hai bản tóm tắt mô hình:

summary(fit)$coefficients[1,4]
summary(fit)$tTable[1,4]  
  • Lưu ý, bạn có thể thay thế số cột bằng tên cột trong mỗi trường hợp trên:

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

Nếu bạn vẫn không chắc chắn về cách truy cập biểu mẫu giá trị, bảng tóm tắt sẽ sử dụng str()để tìm ra cấu trúc của bảng tóm tắt:

str(summary(fit))

7

Đây là cách dễ nhất để kéo các giá trị p:

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

1
Tôi đã thử phương pháp này, nhưng nó sẽ thất bại nếu mô hình tuyến tính chứa bất kỳ thuật ngữ NA nào
j_v_wow_d

5

Tôi đã sử dụng chức năng lmp này khá nhiều lần.

Và tại một thời điểm, tôi quyết định thêm các tính năng mới để tăng cường phân tích dữ liệu. Tôi không phải là chuyên gia về R hoặc thống kê nhưng mọi người thường nhìn vào các thông tin khác nhau của hồi quy tuyến tính:

  • giá trị p
  • A và B
  • và tất nhiên khía cạnh của phân phối điểm

Hãy có một ví dụ. Bạn có ở đây

Dưới đây là một ví dụ có thể lặp lại với các biến khác nhau:

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)

Chắc chắn có một giải pháp nhanh hơn chức năng này nhưng nó hoạt động.


2

Đối với giá trị p cuối cùng được hiển thị ở cuối summary(), hàm sử dụng pf()để tính toán từ các summary(fit)$fstatisticgiá trị.

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

Nguồn: [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
Quan tâm để cung cấp một lời giải thích, ngay cả khi ngắn gọn, tại sao mã này hoạt động?
aribeiro

làm thế nào để cải thiện các câu trả lời hiện có (và đặc biệt là câu trả lời được chấp nhận)?
Ben Bolker

0

Một tùy chọn khác là sử dụng hàm cor.test, thay vì 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

Sử dụng:

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

trong đó nummột số biểu thị hàng của ma trận hệ số. Nó sẽ phụ thuộc vào số lượng tính năng bạn có trong mô hình của mình và tính năng nào bạn muốn lấy giá trị p cho. Ví dụ: nếu bạn chỉ có một biến thì sẽ có một giá trị p cho phần chặn sẽ là [1,4] và biến tiếp theo cho biến thực của bạn sẽ là [2,4]. Vì vậy, bạn numsẽ là 2.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.