编写 loop/function 以在同一数据帧上生成各种线性回归

Writing loop/function to generate various linear regressions on same dataframe

我正在用 R 编写循环或函数,但我还没有真正理解如何去做。目前,我需要编写一个 loop/function(不确定哪个更好)来在同一数据框中创建多个线性回归模型。

我有这样的数据:

dataset <- read.table(text = 
"ID  A_2 B_2 C_2 A_1 B_1 C_1 AGE
M1  10  6   6   8   8   9   25
M2  50  69  54  67  22  44  16
M3  5   80  44  78  5   55  18
M4  60  70  52  89  3   56  28
M5  60  5   34  90  80  56  34
M6  55  55  67  60  100 77  54", header = TRUE, stringsAsFactors = FALSE)

我正在构建这样的模型:

model1 <- lm(A_2~A_1+age, data=dataset)

model2 <- lm(B_2~B_1+age, data=dataset)

model3 <- lm(C_2~C_1+age, data=dataset)

我需要写一个循环:

Dep_va  Ind_var Convarites  Pvalue  "upper.cI" "low.cI" 

A_2 A_1 age         
B_2 B_1 age         
C_2 C_1 age         
D_2 D_1 age         

鉴于您的特定问题,如果您的变量名称带有标有 _2 和 _1 的公共碱基以分别指定因变量和自变量,您可以按如下方式解决您的问题:

var.names <- names(dataset[!names(dataset) %in% c("ID","AGE")])
names.list <- strsplit(var.names,split = "_")
list.of.models <- list()
for (i in 1:length(names.list)) {
DV <- grep(names.list[[i]][1], names(dataset))[1]
IV <- grep(names.list[[i]][1], names(dataset))[2]
  list.of.models[[i]] <- lm(dataset[,DV] ~ dataset[,IV] + AGE, data = dataset)
}

summary(list.of.models[[1]])

Call:
lm(formula = dataset[, DV] ~ dataset[, IV] + AGE, data = dataset)

Residuals:
        1         2         3         4         5         6 
  0.07496  20.42938 -31.36213  10.04093   4.47412  -3.65725 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)
(Intercept)        -15.0439    31.5482  -0.477    0.666
dataset[, IV]        0.4627     0.3319   1.394    0.258
AGE                  0.8507     0.7314   1.163    0.329

Residual standard error: 22.62 on 3 degrees of freedom
Multiple R-squared:  0.5276,    Adjusted R-squared:  0.2127 
F-statistic: 1.676 on 2 and 3 DF,  p-value: 0.3246

这里有一个 tidyverse 方法:

library(tidyverse)

dataset %>% 
  gather(col, val, -ID, -AGE) %>%
  separate(col, c("name", "num")) %>%
  spread(num, val) %>%
  group_by(name) %>%
  group_map(~lm(`2` ~ `1` + AGE, data = .x) %>% broom::tidy())

# A tibble: 9 x 6
# Groups:   name [3]
  name  term        estimate std.error statistic p.value
  <chr> <chr>          <dbl>     <dbl>     <dbl>   <dbl>
1 A     (Intercept)  -15.0      31.5      -0.477  0.666 
2 A     `1`            0.463     0.332     1.39   0.258 
3 A     AGE            0.851     0.731     1.16   0.329 
4 B     (Intercept)   49.1      52.5       0.935  0.419 
5 B     `1`           -0.359     0.801    -0.448  0.685 
6 B     AGE            0.391     2.47      0.159  0.884 
7 C     (Intercept)    5.42     13.9       0.390  0.723 
8 C     `1`            0.932     0.289     3.23   0.0483
9 C     AGE           -0.299     0.470    -0.635  0.570 

解释:

  1. 将数据移动到 long/tidy 格式 gather()
  2. separate 变量类别(在示例数据中,AB 等)
  3. 使用 spread()
  4. 为 IV 和 DV 创建一个单独的列
  5. 使用 group_by()group_map()lm() 应用于每个变量类别。

这是解决 lapply 循环问题的 base R 方法。

首先,如果你想自动提取以_2结尾的变量名,这应该是你所有的因变量,你可以实现以下代码:

dep_vars<-grep("_2$",colnames(dataset),value = T) #This selects all variables ending in `_2` which should all be dependent variables.

reg_vars<-gsub("_2$","",dep_vars) #This removes the `_2` from the dependent variables which should give you the common stem which can be used to select both dependent and independent variables from your data frame.

然后您可以在 lapply 循环中使用它来创建您的公式:

full_results <- lapply(reg_vars, function(i) summary(lm(paste0("log(",i,"_2)~",i,"_1+AGE"),data=dataset)))

现在您将拥有一个线性回归摘要列表,您可以在其中提取所需的信息。我认为这就是您想要的输出,但如果不是,请说明:

print_results<-lapply(full_results,function(i) data.frame(
                                            Dep_va = names(attributes(i[["terms"]])$dataClasses)[1], 
                                            Ind_var = names(attributes(i[["terms"]])$dataClasses)[2],
                                            Covariates = names(attributes(i[["terms"]])$dataClasses)[3], 
                                            Pvalue = i[["coefficients"]][2,4],
                                            upper.cI = i[["coefficients"]][2,1]+1.96*i[["coefficients"]][2,2],
                                            low.cI = i[["coefficients"]][2,1]-1.96*i[["coefficients"]][2,2]))

该代码将为您提供一个数据框列表,如果您想将其合并为一个 data.frame:

final_results<-do.call("rbind",print_results)

输出结果:

Dep_va Ind_var Covariates     Pvalue upper.cI     low.cI
1    A_2     A_1        AGE 0.25753805 1.113214 -0.1877324
2    B_2     B_1        AGE 0.68452053 1.211355 -1.9292236
3    C_2     C_1        AGE 0.04827506 1.497688  0.3661343

希望对您有所帮助!如果您正在寻找不同的输出结果,请告诉我。