витягнути р-значення та r-квадрат з лінійної регресії


179

Як ви виводите значення р (якщо значення коефіцієнта єдиної пояснювальної змінної є ненульовим) та значення R-квадрата з простої лінійної регресійної моделі? Наприклад...

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

Я знаю, що summary(fit) відображає значення p-значення та R-квадрата, але я хочу мати змогу вставити їх в інші змінні.


Він відображає значення лише у тому випадку, якщо ви не призначите вихід об'єкту (наприклад, r <- summary(lm(rnorm(10)~runif(10)))нічого не відображає).
— Джошуа Ульріх

Відповіді:


157

r-квадрат : Ви можете повернути значення r-квадрата безпосередньо з об'єкта зведення summary(fit)$r.squared. Перегляньте names(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

У випадку простої регресії з одним предиктором модель p-значення та p-значення для коефіцієнта будуть однаковими.

Коефіцієнт p-значення: Якщо у вас є більше одного прогноктора, то вищезгадане поверне модельне p-значення, а p-значення для коефіцієнтів можна отримати, використовуючи:

summary(fit)$coefficients[,4]  

Крім того, ви можете схопити p-значення коефіцієнтів від anova(fit)об'єкта аналогічно вищезведеному об'єкту.


13
Це трохи краще використовувати, inheritsа не classбезпосередньо. А може, ти хочеш unname(pf(f[1],f[2],f[3],lower.tail=F))?
— Хадлі

150

Зауважте, що summary(fit)генерується об’єкт з усією необхідною інформацією. Вектори бета, se, t і p зберігаються в ньому. Отримайте значення p, вибравши 4-й стовпчик матриці коефіцієнтів (зберігається в об'єкті підсумків):

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

Спробуйте str(summary(fit))переглянути всю інформацію, яку містить цей об’єкт.

Редагувати: Я неправильно прочитав відповідь Чейза, яка в основному говорить вам, як дістатися до того, що я даю тут.


11
Примітка: це єдиний метод, який дає вам легкий доступ до p-значення перехоплення, а також до інших прогнозів. На сьогоднішній день найкраще.
— Даніель Еган

2
Це ПРАВА відповідь. Відповідь з найвищим рейтингом НЕ працював для мене.
— Кріс,

8
ЯКЩО Ви хочете ЛЕГИЙ ДОСТУП ДО П-ЦІННОСТІ, ВИКОРИСТУЙТЕ ЦІЙ ВІДПОВІДЬ. Чому ви переходите до написання багаторядкових функцій або створення нових об'єктів (тобто, anova output), коли вам потрібно буде трохи важче подивитися на значення p у самому підсумковому висновку. Для виділення окремого сам р-значення, потрібно додати номер рядка у відповідь Вінсент: наприклад, summary(fit)$coefficients[1,4] для thei ntercept
— theforestecologist

2
Примітка. Цей метод працює для моделей, створених за допомогою, lm()але не працює для gls()моделей.
— theforestecologist

3
Відповідь Чейза повертає p-значення моделі, ця відповідь повертає p-значення коефіцієнтів. У випадку простої регресії вони однакові, але у випадку з моделлю з декількома предикторами вони не однакові. Таким чином, обидві відповіді корисні залежно від того, що ви хочете витягти.
— Джеромі Англім

44

Ви можете бачити структуру об'єкта, що повертається summary(), зателефонувавши str(summary(fit)). Кожен фрагмент можна отримати за допомогою $. Значення p для статистики F легше було від об'єкта, повернутого anova.

Точно, ви можете це зробити:

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

10
це працює лише для одноманітних регресій, де р вал регресії той самий, що й
— прогноктор

23

Хоча обидві відповіді вище хороші, процедура вилучення частин предметів є більш загальною.

У багатьох випадках до функцій повертаються списки, а до окремих компонентів можна отримати доступ, використовуючи для str()цього друк компонентів разом з їх назвами. Потім ви можете отримати доступ до них за допомогою оператора $, тобто myobject$componentname.

У разі об'єктів лм, існує цілий ряд зумовлених методів можна використовувати , наприклад , як 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"

Це чудова відповідь!
— Андрій Бреза

9

Розширення @Vincent «s відповідь :

Для 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 або статистики, але люди зазвичай дивляться на різну інформацію лінійної регресії:

  • р-значення
  • а і б
  • r²
  • і, звичайно, аспект розподілу точок

Будемо мати приклад. Ви тут

Ось відтворюваний приклад з різними змінними:

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
Потрібно дати пояснення, навіть якщо коротко, чому цей код працює?
— арібейро

як це покращується на існуючих відповідях (і зокрема на прийнятій відповіді)?
— Бен Болкер

0

Іншим варіантом є використання функції cor.test замість 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

Використання:

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

де numчисло, яке позначає рядок матриці коефіцієнтів. Це залежатиме від того, скільки функцій у вашій моделі є і для якої ви хочете витягнути значення p. Наприклад, якщо у вас є лише одна змінна, буде одне p-значення для перехоплення, яке буде [1,4], і наступне для вашої фактичної змінної, яке буде [2,4]. Тож ваша numбуде 2.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.