关于统计:是否有任何方法可以通过从R中的模型中获取参数来构造真实的回归方程?

Is there any way to construct real regression equation by taking parameters from models in R?

数据是:

1
2
3
d <- data.frame(x = rnorm(100, 0, 1),
            y = rnorm(100, 0, 1),
            z = rnorm(100, 0, 1))

功能适合5种型号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
library(splines)
func <-function(d){
  fit1 <- lm( y~ x + z, data = d)
  fit2 <- lm( y~x + I(z^2), data = d)
  fit3 <- lm( y~poly(x,3) + z, data = d)
  fit4 <- lm( y~ns(x, 3) + z, data = d)
  l <- list(fit1, fit2, fit3, fit4)
  names(l) <- paste0("fit", 1:4)
  return(l)
}

mods <- func(d)
mods[[1]]

stargazer(mods, type="text)

我想通过尽可能从R内自动拟合模型和ind变量中获取参数,以每个模型的真实格式构造真实的回归方程式。例如:对于fit1模型,intercept = -0.20612,x = 0.17443,x = 0.03203。然后方程将是这样的:y = -0.206 0.174x 0.032z等,并希望在表格中列出所有模型的方程,以及非常常见的有用统计数据,例如R2,P值,R2,观测值等。给我看我想要的输出。因此,我想确保是否有任何方法可以在R中执行此操作,而无需在excel中手动执行此操作?

预先感谢!


我们可以使用@ J.R.的函数通过 map,并使用broom::glance到模型R2,P值和调整R2。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
library(purrr)
library(broom)
map_dfr(mods,
        function(x) data.frame('Eq'=regEq(lmObj = x, dig = 3), broom::glance(x), stringsAsFactors = FALSE),
        .id='Model')

  Model                                                                              Eq    r.squared adj.r.squared    sigma  statistic   p.value df    logLik      AIC      BIC
1  fit1                                                   y = 0.091 - 0.022*x - 0.027*z 0.0012601436   -0.01933243 1.028408 0.06119408 0.9406769  3 -143.1721 294.3441 304.7648
2  fit2                                              y = 0.093 - 0.022*x - 0.003*I(z^2) 0.0006154188   -0.01999045 1.028740 0.02986619 0.9705843  3 -143.2043 294.4087 304.8294
3  fit3 y = 0.093 - 0.248*poly(x, 3)1 - 0.186*poly(x, 3)2 - 0.581*poly(x, 3)3 - 0.031*z 0.0048717358   -0.03702840 1.037296 0.11627016 0.9764662  5 -142.9909 297.9819 313.6129
4  fit4        y = 0.201 + 0.08*ns(x, 3)1 - 0.385*ns(x, 3)2 - 0.281*ns(x, 3)3 - 0.031*z 0.0032813558   -0.03868575 1.038125 0.07818877 0.9887911  5 -143.0708 298.1416 313.7726
  deviance df.residual
1 102.5894          97
2 102.6556          97
3 102.2184          95
4 102.3818          95


问题是您的每个模型都不完全适合表格数据,例如,拟合3返回4个估计,而拟合1仅返回3个

如果您对列表感到满意,我建议它们是一种存储此类信息的好方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
library(broom)
library(tidyverse)
library(splines)

d <- data.frame(x = rnorm(100, 0, 1),
                y = rnorm(100, 0, 1),
                z = rnorm(100, 0, 1))

func <-function(d){
  fit1 <- lm( y~ x + z, data = d)
  fit2 <- lm( y~x + I(z^2), data = d)
  fit3 <- lm( y~poly(x,3) + z, data = d)
  fit4 <- lm( y~ns(x, 3) + z, data = d)
  l <- list(fit1, fit2, fit3, fit4)
  names(l) <- paste0("fit", 1:4)
  return(l)
}

mods <- func(d)

list_representation<- map(mods,tidy)


假设最后的注释中显示的mods,并且想要的是替换了系数的公式的文本表示的字符向量,我们具有以下内容。

fit2text函数获取一个已拟合的对象,并输出带有公式文本表示形式的字符串。 round自变量给出系数在结果中四舍五入到的位数。 rmI参数(如果为TRUE)将删除任何I(...)并仅将...留在...内部,并假设为了便于实现,该表达式不包含任何括号。如果为FALSE,则不会删除I

可以从summary(mods[[1]])broom::glance(mods[[1]])

中提取其他统计信息

1
2
3
4
5
6
7
8
9
10
fit2text <- function(fit, round = 2, rmI = TRUE) {
  fo <- formula(fit)  
  resp <- all.vars(fo)[1]
  co <- round(coef(fit), round)
  labs <- c(if (terms(fit,"intercept") == 1)"", labels(fit))
  p <- gsub("\\\\+ *-","-", paste(resp,"~", paste(paste(co, labs), collapse =" +")))
  p2 <- if (rmI) gsub("I\\\\(([^)]+)\\\\)","\\\\1", p) else p
  gsub(" +","", p2)
}
sapply(mods, fit2text)

给予:

1
2
3
4
5
6
7
8
                                                           fit1
                                 "y ~ -0.11 - 0.05 x + 0.03 z"
                                                           fit2
                               "y ~ -0.07 - 0.05 x - 0.04 z^2"
                                                           fit3
"y ~ -0.11 - 0.43 poly(x, 3) - 1.05 z + 0.27 + 0.04 poly(x, 3)"
                                                           fit4
   "y ~ -0.55 + 0.23 ns(x, 3) + 0.79 z - 0.25 + 0.04 ns(x, 3)"

笔记

问题中的代码不可复制,因为缺少库调用,它使用了不带set.seed的随机数,并且代码中还有一些其他错误。为了清楚起见,我们提供了以下可重复使用的代码,用于为上述答案提供输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
library(splines)
set.seed(123)

d <- data.frame(x = rnorm(100, 0, 1),
            y = rnorm(100, 0, 1),
            z = rnorm(100, 0, 1))

# function to fit 5 models
func <-function(d){
  fit1 <- lm( y~ x + z, data = d)
  fit2 <- lm( y~x + I(z^2), data = d)

  fit3 <- lm( y~poly(x,3) + z, data = d)
  fit4 <- lm( y~ns(x, 3) + z, data = d)
  l <- list(fit1, fit2, fit3, fit4)
  names(l) <- paste0("fit", 1:4)
  return(l)
}

mods <- func(d)