R中按组运行的数百个线性回归

时间:2018-07-28 04:01:47

标签: r linear-regression

我有一个包含3,000多个行和10多个变量的表。我正在尝试使用一个变量作为预测变量,将另一个变量作为对300个不同组的响应进行线性回归。对于每个回归,我都需要斜率,p值和r平方。单独进行每个回归并记录摘要变量将花费数小时甚至数天。

我已经使用以下程序包获取每个组的截距和斜率,但是我不知道如何获取每个组的相应p值和r平方:

library(lme4)
groupreg<-lmList(logpop ~ avgp | id, data=data)
groupreg

我在下面获得了一个列表示例,其中“亚当斯#”是id值。之所以存在NA,是因为并非所有组都有多个要绘制和比较的点:

Coefficients:
                (Intercept)          avgp
Adams 6           4.0073332            NA
Adams 7           6.5177389 -7.342443e+00
Adams 8           4.7449321            NA
Adams 9                  NA            NA

但是,此表不包括任何重要度统计信息。我仍然需要p值和r平方统计量。如果有一个代码可以一次完成所有组值,或者有一个代码仅提取其余值,那将很有帮助。

是否还有办法对所有组的斜率输出求幂?我的结果被对数转换。

谢谢大家!

3 个答案:

答案 0 :(得分:3)

我认为最简单的答案仍然缺失。您可以结合使用嵌套和映射。我将向您展示它如何用于线性回归。我认为您可以将相同的原理应用于lme4软件包的模型。

让我们创建一个玩具数据集,我们在其中测量了两个不同时间点上三个不同组的智商得分。

library(tidyverse)
library(broom)

df <- tibble(
  id = seq_len(90),
  IQ = rnorm(90, 100, 15),
  group = rep(c("A", "B", "C"), each = 30),
  time = rep(c("T1", "T2"), 45)
)

如果我们要为每个组建立一个回归模型,研究IQ得分与时间点之间的关系,我们只需要五行代码。

df %>% 
  nest(-group) %>% 
  mutate(fit = map(data, ~ lm(IQ ~ time, data = .)),
         results = map(fit, glance)) %>% 
  unnest(results) %>% 
  select(group, r.squared, p.value) 

哪个会回来

 # A tibble: 3 x 3
  group r.squared p.value
  <chr>     <dbl>   <dbl>
1 A       0.0141    0.532
2 B       0.0681    0.164
3 C       0.00432   0.730

其中nest(-group)tibbles中为每个组创建tibble,其中包含idIQtime的相应变量。然后,用fit添加一个新列mutate(),在其中为每个组应用一个回归模型,并在一个包含结果的新列中使用unnest(),不久之后我们就可以访问值{{1 }}正确返回。在最后一步,我们glance()感兴趣的三个值。

要获取斜率,您还需要致电select()。也许可以以某种方式缩短代码,但是一种解决方案是

tidy()

要对斜率求幂,只需添加另一个df %>% nest(-group) %>% mutate(fit = map(data, ~ lm(IQ ~ time, data = .)), results1 = map(fit, glance), results2 = map(fit, tidy)) %>% unnest(results1) %>% unnest(results2) %>% select(group, term, estimate, r.squared, p.value) %>% mutate(estimate = exp(estimate)) 语句。最后返回

mutate()

请注意,估计值已取幂。如果没有幂运算,则可以使用# A tibble: 6 x 5 group term estimate r.squared p.value <chr> <chr> <dbl> <dbl> <dbl> 1 A (Intercept) 3.34e+46 0.0141 0.532 2 A timeT2 3.31e- 2 0.0141 0.532 3 B (Intercept) 1.17e+47 0.0681 0.164 4 B timeT2 1.34e- 3 0.0681 0.164 5 C (Intercept) 8.68e+43 0.00432 0.730 6 C timeT2 1.25e- 1 0.00432 0.730 调用

来仔细检查斜率和p值
base R

如果您使用更复杂的模型(summary(lm(IQ ~ time, data = filter(df, group == "A"))) ),则有一个名为lmerTest的程序包,它为lme4提供了包装函数,这些函数返回p值(至少对于混合模型,与我已经合作过的。)

应该对在lme4模型中使用glance()表示警告,因为lme4软件包的维护者将尝试使用new concept,将摘要汇总统计给负责该模型的特定程序包开发人员。

答案 1 :(得分:1)

尽管AndS给出的代码可以正常工作,但它将为每个组运行lm函数4次,这使其效率低下。您可以使用以下内容。我正在尝试将其分解为更简单的步骤:

假设您的数据帧(df)具有三个变量:“组”,“ Dep”,“独立”:

.FancyBorder-blue {
  border-color: blue;
}

在每个模型摘要中,您都有以下元素RSQ,系数(也包含p值和截距)

让我知道这是否有帮助。

答案 2 :(得分:0)

如果我正确地理解了您的问题,则希望对许多组进行多次回归。这是如何使用mtcars数据的示例。

library(dplyr)
mtcars %>% group_by(cyl) %>% 
    summarise_at(vars(disp:wt), funs(
        r.sqr = summary(lm(mpg~.))$r.squared,
        intercept = summary(lm(mpg~.))$coefficients[[1]],
        slope = summary(lm(mpg~.))$coefficients[[2]],
        p.value = summary(lm(mpg~.))$coefficients[[8]]
    ))

这将对每个组的每个变量进行回归,并提取您要求的信息。如果您的公式始终相同,则可以简化如下。

mtcars %>% group_by(cyl) %>% 
    summarise(
        r.sqr = summary(lm(mpg~wt))$r.squared,
        intercept = summary(lm(mpg~wt))$coefficients[[1]],
        slope = summary(lm(mpg~wt))$coefficients[[2]],
        p.value = summary(lm(mpg~wt))$coefficients[[8]]
    )

这实际上是运行回归4次(每个兴趣值一次)。如果实际数据花费的时间太长,则可以尝试以下操作:

df <- mtcars %>% group_by(cyl) %>% summarise(model = list(summary(lm(mpg~wt))))

只需每个组运行一次​​模型,然后提取所需的信息。问题在于以这种方式提取值可能会很痛苦

df$model[[1]]$coefficients[[1]]
[1] 39.5712