在R中,跨多列对数据框进行Lm回归分析

3
我有一个包含许多数值列的数据框,需要将第一列回归到第二列,然后存储Rsqr值,接着将第一列回归到第三列,再存储Rsqr值......以此类推,直到第n列被回归到第一列。
我希望结果是一个数据框,其中包含回归所得的Rsqr值与对应的列名。
例如:
tested              rqr
col1 v col2         0.56
col1 v col3         0.28
col1 v col4         0.38

我知道我没有提供数据 - 我正在寻找方法。我曾经在for循环中使用一个名为lm的函数来完成这个任务,但是它非常耗时。我想知道是否有一种apply方法可以解决这个问题。

保罗


4
始终提供数据。至少可以让你获得额外的好感分。 - Roland
5个回答

2
如果你只需要R²,你不需要拟合线性模型,而是可以直接计算Pearson相关系数。这将给出所有列之间的相关性:
cor(yourDataFrame)^2

以下是与第一列相关的示例:

set.seed(42)
df<-as.data.frame(matrix(rnorm(100), ncol = 4)) 
cor(df, df[,1])^2
#          [,1]
#V1 1.000000000
#V2 0.006508638
#V3 0.110714099
#V4 0.006231468

2

这是一个dplyr方法。其哲学是将列名组合在一起,为每个你想要实现的回归创建一个公式。

library(dplyr)

dt = data.frame(mtcars)

# specify columns to regress
y_col = "disp"
x_col = c("mpg","cyl","hp")

expand.grid(y=y_col, x=x_col, stringsAsFactors = F) %>%
  mutate(formula = paste(y,"~",x)) %>%
  group_by(formula) %>%
  mutate(r_sq = summary(lm(formula, data=dt))$r.squared) %>%
  ungroup()


#       y     x    formula      r_sq
#   (chr) (chr)      (chr)     (dbl)
# 1  disp   mpg disp ~ mpg 0.7183433
# 2  disp   cyl disp ~ cyl 0.8136633
# 3  disp    hp  disp ~ hp 0.6255997

@Roland的评论非常有用,因为它可以在你有大量数据的情况下加快事情进展。根据你的问题,我将专注于执行多元回归分析。 - AntoniosK

2

以下是使用一些典型的 dplyr/purrr/tidyr/broom 习语的方法:

加载库:

library(dplyr)
library(purrr)
library(tidyr)
library(broom)

以下是数据:

dt = mtcars # already a dataframe

以下是针对列mpgcylhp与列disp进行分别线性回归计算,并获取每个回归的R平方值的序列:

dt %>% 
  select(disp, mpg, cyl, hp) %>% 
  gather(key = group, 
         value = measurement,
         -disp) %>% 
  group_by(group) %>% 
  nest() %>%
  mutate(model = map(data, ~lm(disp ~ measurement, data = .))) %>% 
  unnest(model %>% map(glance))

以下是输出结果:
Source: local data frame [3 x 14]

  group            data   model r.squared adj.r.squared    sigma
  (chr)           (chr)   (chr)     (dbl)         (dbl)    (dbl)
1   mpg <tbl_df [32,2]> <S3:lm> 0.7183433     0.7089548 66.86320
2   cyl <tbl_df [32,2]> <S3:lm> 0.8136633     0.8074521 54.38465
3    hp <tbl_df [32,2]> <S3:lm> 0.6255997     0.6131197 77.08950
Variables not shown: statistic (dbl), p.value (dbl), df (int), logLik
  (dbl), AIC (dbl), BIC (dbl), deviance (dbl), df.residual (int)

用通俗易懂的语言叙述这个流程:

  • 我们首先取得数据框,然后
  • 将其从宽格式转换为长格式以创建一个分组列,然后
  • 使用每个组的一行来创建一个嵌套的数据框,接下来
  • 对于每个组计算一个线性模型,最后
  • 将模型的输出(包括R平方值)提取到一个数据框中。

0

尝试

set.seed(1)
df<-as.data.frame(matrix(rnorm(100),10)) # reproducible data
paste0('col1 vs col',2:10)->column1 # first column : the regression
sapply(2:10,function(x){summary(lm(df[,1]~df[,x]))$r.squared})->column2 # the rsquared
final<-data.frame('reg'=column1,'rsquared'=column2) # the final data.frame

        final
            reg   rsquared
1  col1 vs col2 0.14190543
2  col1 vs col3 0.51242469
3  col1 vs col4 0.05973700
4  col1 vs col5 0.05149017
5  col1 vs col6 0.37621382
6  col1 vs col7 0.14208468
7  col1 vs col8 0.38533983
8  col1 vs col9 0.26596917
9 col1 vs col10 0.01758616

抱歉,我忘了说任何一个列中可能会出现一些NAs - 它们可以在apply调用的过程中被删除吗? 我不想在开始之前删除NAs,因为那样可能会丢失许多行......只需要删除在测试的两个列之间的NAs。 - PaulBeales
@PaulBeales:请查看此链接以了解关于NAlm的信息:http://stats.stackexchange.com/questions/11000/how-does-r-handle-missing-values-in-lm - etienne
默认情况下,在lm调用中它们被省略。 - etienne
当我运行sapply代码时,出现了以下错误。 Error in summary.lm(lm(df[, 1] ~ df[, x])) : length of 'dimnames' [1] not equal to array extent - PaulBeales
然后请键入 dput(df)。拥有数据会非常有帮助。您可以只写 summary() 而不是 summary.lm() - etienne
@PaulBeales:同时你需要将 2:10 调整为实际的列数。 - etienne

0
从 @etienne 的解决方案中借鉴大指针,下面是 data.table 的答案。
library(data.table)

set.seed(1)
df <- as.data.frame(matrix(rnorm(100),10))
dt = setDT(df)
melt(dt, id.vars = "V1")[!is.na(value) & !is.na(V1),  # rm NAs
                         summary(lm(V1~value))$r.squared,  # lm call
                         variable]  # for each column

   variable         V1
1:       V2 0.14190543
2:       V3 0.51242469
3:       V4 0.05973700
4:       V5 0.05149017
5:       V6 0.37621382
6:       V7 0.14208468
7:       V8 0.38533983
8:       V9 0.26596917
9:      V10 0.01758616

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接