编写 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)
我需要写一个循环:
- 采用
variable _2
(因变量)和variable _1
(自变量)和协变量,如age
...
- 创建
lm
模型,并将输出(即 T 值、p 值、置信区间等)存储在我可以打印的 data.frame 中。
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
解释:
- 将数据移动到 long/tidy 格式
gather()
separate
变量类别(在示例数据中,A
、B
等)
- 使用
spread()
为 IV 和 DV 创建一个单独的列
- 使用
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
希望对您有所帮助!如果您正在寻找不同的输出结果,请告诉我。
我正在用 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)
我需要写一个循环:
- 采用
variable _2
(因变量)和variable _1
(自变量)和协变量,如age
... - 创建
lm
模型,并将输出(即 T 值、p 值、置信区间等)存储在我可以打印的 data.frame 中。
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
解释:
- 将数据移动到 long/tidy 格式
gather()
separate
变量类别(在示例数据中,A
、B
等)- 使用
spread()
为 IV 和 DV 创建一个单独的列
- 使用
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
希望对您有所帮助!如果您正在寻找不同的输出结果,请告诉我。