用于 R 中多列回归的嵌套循环
Nested loop for regression over several columns in R
我有两个数据框。一个是我的数据:
test <- structure(list(IDcount = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), year = c(1,
2, 3, 4, 5, 1, 2, 3, 4, 5), Otminus1 = c(-0.28, -0.28, -0.44,
-0.27, 0.23, -0.03, -0.06, -0.04, 0, 0.02), N.1 = c(-0.76, -0.1,
0.01, 0.1, -0.04, -0.04, -0.04, -0.04, -0.05, -0.05), N.2 = c(NA,
-0.86, -0.09, 0.11, 0.06, -0.05, -0.08, -0.08, -0.09, -0.09),
N.3 = c(NA, NA, -0.85, 0.01, 0.07, -0.04, -0.09, -0.12, -0.13,
-0.13)), row.names = c(NA, -10L), groups = structure(list(
IDcount = c(1, 2), .rows = structure(list(1:5, 6:10), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = 1:2, class = c("tbl_df",
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
还有一个捕捉我的回归结果:
results <- structure(list(IDcount = c(1, 2), N.1 = c(NA, NA), N.2 = c(NA,
NA), N.3 = c(NA, NA), N.4 = c(NA, NA), N.5 = c(NA, NA)), row.names = c(NA,
-2L), class = "data.frame")
我 运行 对我的数据进行回归,其中每个公司都被分配了一个系数,代码如下:
betas <- matrix(nrow=2, ncol=2)
colnames(betas) <- c("Intercept", "beta")
for (i in 1:2) {
betas[i,] <- coef(lm(Otminus1~N.1, test[test$IDcount==i,]))
}
betas <- data.frame(betas)
results$N.1 <- betas$beta
我现在想将此循环嵌套在一个循环中,以便在回归和结果数据框中使用的列从 1 移动到 3。使用循环应该导致 N.1 到 N 列中的值.5 在数据框结果中。
这是我对此的错误方法:
for (j in 1:5) {
for (i in 1:2) {
betas[i,] <- coef(lm(Otminus1~N.j, test[test$IDcount==i,]))
}
betas <- data.frame(betas)
results$N.j <- betas$beta
}
但是这个循环无法将 N.j 中的 j 识别为 for 循环变量之一。
通过在 N.j
列名称上迭代 j 来尝试此代码:
library(dplyr)
library(stringr)
index <- colnames(test) %>% str_which("N.")
for (j in colnames(test)[index]) {
for (i in 1:2) {
betas[i,] <- coef(lm(Otminus1~., test[test$IDcount==i, c("Otminus1", j)]))
}
betas <- data.frame(betas)
results[[j]] <- betas$beta
}
您可以使用 dplyr
和 tidyr
并摆脱 for
循环。
library(dplyr) #dplyr > 1.0.0
library(tidyr)
test %>%
pivot_longer(cols = starts_with('N')) %>%
group_by(IDcount, name) %>%
summarise(value = coef(lm(Otminus1~value, cur_data()))) %>%
slice(2L) %>%
pivot_wider()
# IDcount N.1 N.2 N.3
# <dbl> <dbl> <dbl> <dbl>
#1 1 0.0756 0.190 0.499
#2 2 -5.33 -0.815 -0.412
我有两个数据框。一个是我的数据:
test <- structure(list(IDcount = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), year = c(1,
2, 3, 4, 5, 1, 2, 3, 4, 5), Otminus1 = c(-0.28, -0.28, -0.44,
-0.27, 0.23, -0.03, -0.06, -0.04, 0, 0.02), N.1 = c(-0.76, -0.1,
0.01, 0.1, -0.04, -0.04, -0.04, -0.04, -0.05, -0.05), N.2 = c(NA,
-0.86, -0.09, 0.11, 0.06, -0.05, -0.08, -0.08, -0.09, -0.09),
N.3 = c(NA, NA, -0.85, 0.01, 0.07, -0.04, -0.09, -0.12, -0.13,
-0.13)), row.names = c(NA, -10L), groups = structure(list(
IDcount = c(1, 2), .rows = structure(list(1:5, 6:10), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = 1:2, class = c("tbl_df",
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
还有一个捕捉我的回归结果:
results <- structure(list(IDcount = c(1, 2), N.1 = c(NA, NA), N.2 = c(NA,
NA), N.3 = c(NA, NA), N.4 = c(NA, NA), N.5 = c(NA, NA)), row.names = c(NA,
-2L), class = "data.frame")
我 运行 对我的数据进行回归,其中每个公司都被分配了一个系数,代码如下:
betas <- matrix(nrow=2, ncol=2)
colnames(betas) <- c("Intercept", "beta")
for (i in 1:2) {
betas[i,] <- coef(lm(Otminus1~N.1, test[test$IDcount==i,]))
}
betas <- data.frame(betas)
results$N.1 <- betas$beta
我现在想将此循环嵌套在一个循环中,以便在回归和结果数据框中使用的列从 1 移动到 3。使用循环应该导致 N.1 到 N 列中的值.5 在数据框结果中。 这是我对此的错误方法:
for (j in 1:5) {
for (i in 1:2) {
betas[i,] <- coef(lm(Otminus1~N.j, test[test$IDcount==i,]))
}
betas <- data.frame(betas)
results$N.j <- betas$beta
}
但是这个循环无法将 N.j 中的 j 识别为 for 循环变量之一。
通过在 N.j
列名称上迭代 j 来尝试此代码:
library(dplyr)
library(stringr)
index <- colnames(test) %>% str_which("N.")
for (j in colnames(test)[index]) {
for (i in 1:2) {
betas[i,] <- coef(lm(Otminus1~., test[test$IDcount==i, c("Otminus1", j)]))
}
betas <- data.frame(betas)
results[[j]] <- betas$beta
}
您可以使用 dplyr
和 tidyr
并摆脱 for
循环。
library(dplyr) #dplyr > 1.0.0
library(tidyr)
test %>%
pivot_longer(cols = starts_with('N')) %>%
group_by(IDcount, name) %>%
summarise(value = coef(lm(Otminus1~value, cur_data()))) %>%
slice(2L) %>%
pivot_wider()
# IDcount N.1 N.2 N.3
# <dbl> <dbl> <dbl> <dbl>
#1 1 0.0756 0.190 0.499
#2 2 -5.33 -0.815 -0.412