如何在 for 循环中对数据集的所有变量应用回归,同时在 R 中添加行
How to apply a regression in a for loop for all the variables of a dataset while adding rows in R
我知道这是一个很长的问题,但请耐心等待。
我有一个这种形式的数据集:
head(TRAINSET)
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 Y
1 -2.973012 -2.956570 -2.386837 -0.5861751 4e-04 0.44 0.0728 0.0307 0.0354 0.0078 0.0047 0.0100 -0.0022 0.0038 -0.005200012
2 -2.937649 -2.958624 -2.373960 -0.5636891 5e-04 0.44 0.0718 0.0323 0.0351 0.0075 0.0028 0.0095 -0.0019 0.0000 0.042085781
3 -2.984238 -2.937649 -2.428712 -0.5555258 2e-04 0.43 0.0728 0.0329 0.0347 0.0088 0.0018 0.0092 -0.0019 -0.0076 0.004577122
4 -2.976535 -2.970053 -2.443424 -0.5331107 9e-04 0.47 0.0588 0.0320 0.0331 0.0253 0.0011 0.0092 -0.0170 -0.0076 0.010515970
5 -2.979631 -2.962549 -2.468805 -0.5108256 6e-04 0.46 0.0613 0.0339 0.0333 -0.0005 -0.0006 0.0090 0.0060 -0.0058 0.058487141
6 -3.030536 -2.979631 -2.528079 -0.5024574 3e-04 0.43 0.0562 0.0333 0.0327 0.0109 -0.0006 0.0093 -0.0120 0.0000 -0.022896759
这是我的Train集,有300行。剩下的 700 行是测试集。我想要完成的是:
- 对于每一列拟合这种形式的线性模型:Y ~ X1。
- 使用创建的模型通过使用测试集的第一个 X1 获得 Y 的预测值。
- 之后,取Test set的第一行并rbind到Train set(现在Train set是301行)
- 使用测试集中 X1 的第 2 行预测 Y 的值。
- 对测试集的剩余 699 行重复上述操作。
- 将其应用于数据集 (X2,...,X14) 的所有剩余变量。
当我应用我为每个变量专门制作的代码时,我已经设法产生了准确的结果:
fittedvaluess<-NULL #empty set to fill
for(i in 1:nrow(TESTSET)){ #beggin iteration over the rows of Test set
TRAINSET<-rbind(TRAINSET,TESTSET[i,]) #add the rows to the train set
LM<-lm(Y~X1,TRAINSET) #fit the evergrowing OLS
predictd<-predict(LM,TESTSET[i+1,],type = "response") #get the predicted value
fittedvaluess<-cbind(fittedvaluess,predictd) #get the vector of the predicted values
print(cbind(i,length(TRAINSET$LHS),length(TRAINSET$DP),nrow(TRAINSET))) #to make sure it works
}
但是,我想自动执行此操作并在列上重复它。我做了这个:
data<-TRAINSET #cause every time i had to remake the trainset
fittedvaluesss<-NULL
for(i in 1:nrow(TESTSET){ #begin iteration on rows of Testset
data<-rbind(data,TESTSET[i,]) # rbind the rows to the Trainset called data
for(j in 1:ncol(TESTSET){ #iterate over the columns
LM<-lm(data$LHS~data[,j],data) #fit OLS
predictd<-predict(LM,TESTSET[i+1,j],type = "response") #get the predicted value
fittedvaluesss<-cbind(fittedvaluesss,predictd) #derive the predicted value
print(c(i,j)) #make sure it works
}
}
不幸的是,结果是错误的:拟合值是一个巨大的矩阵:
dim(fittedvaluesss)
[1] 2306 3167 #Stopped around the middle of its run
这没有任何意义。我什至 运行
i in 1:3
and
j in 1:3
而且矩阵仍然非常大。我试过从列开始迭代,然后遍历行。完全一样的错误结果。出于某种原因,在每个 运行 中,我从 PREDICT 函数中至少获得了 362 个值。我真的被这个问题困住了。
非常欢迎任何帮助。
编辑 1:这在金融中也称为递归预测方法。这是一种根据当前数据集的模型拟合预测未来值的方法。
考虑使用外循环中的列和内循环中的行来反转循环逻辑。此外,尝试使用 returns 结构比 for
循环更符合您的需求的嵌套应用函数。具体来说,内部 vapply()
return 是每个迭代列的所有测试集预测值的数值向量。然后外部 sapply()
将每个 returned 向量绑定到矩阵的一列。
最终,fittedvaluess
是一个维度为 TESTSET nrow X TESTSET ncol
的矩阵。还要注意,外循环省略了最后一列,因为您不会在 Y 上回归 Y。
fittedvaluess <- sapply(1:(ncol(TESTSET)-1), function(c){
col <- names(TESTSET)[[c]] # RETRIEVE COLUMN NAME FOR LM FORMULA
predictvals <- vapply(1:nrow(TESTSET), function(r){
TRAINSET <- rbind(TRAINSET, TESTSET[1:r,]) # BINDING ROWS ON AND PRIOR TO CURRENT ROW
LM <- lm(paste0("Y~", col), TRAINSET) # CONCATENATED STRING FORMULA
predictd <- predict(LM, TESTSET[r+1,], type="response")
}, numeric(1))
})
为什么要申请和申请?
sapply()
和 vapply()
都是 lapply()
的包装器。其中 sapply()
(simple lapply) 可以 return 向量或矩阵,vapply()
(verified lapply) 允许您专门选择 returned 输出——向量、列表、矩阵——以及类型和长度。所以 vapply
需要第三个参数来指定这样的标准。在这里,我们选择一个长度(或一个对象)的数值向量:numeric(1)
。由于这个预先指定,vapply()
在某些情况下往往 运行 比 lapply()
快。如果我们只选择一般 lapply()
,我们将需要 运行 列表输出的各种转换和转换以与矩阵输出对齐。在某种程度上,我们可以完成嵌套 vapply()
循环!
通过使用下面的代码,它是我原始代码的次要版本,除了我没有使用 predict
#EXPAND IT INTO DOING SO IN ALL COLUMNS
data<-TRAINSET
fittedvaluesss<-NULL
for(i in 1:nrow(TESTSET)){ #go each row
data<-rbind(data,TESTSET[i,]) #update the dataset
for(j in 1:ncol(TESTSET)){ #repead for each column the following
LM<-lm(data$LHS~data[,j]) #OLS reg
predictd<-coef(LM)[1]+coef(LM)[2]*TESTSET[i+1,j] #Simply apply the formula yourself A+Bx for each new iteration
#predict(LM,TESTSET[i+1,j],type = "response")
print(length(predictd)) #makes sure it is ONE value
fittedvaluesss<-c(fittedvaluesss,predictd)
print(c(i,j))
}
}
matrixa<-matrix(fittedvaluesss,15,648) #put the values in a matrix: Note that the Ypreds are in every row
matrixa<-t(matrixa) #transpose in order to have each Ypred from a var in a column
之所以可行,是因为每次迭代的预测函数 return 是一个大小为 361x15
的小矩阵( 在我的初始代码中 )和那是一次迭代。因此我放弃了预测功能并使用了系数本身。这似乎 return 是正确的预测。
我知道这是一个很长的问题,但请耐心等待。
我有一个这种形式的数据集:
head(TRAINSET)
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 Y
1 -2.973012 -2.956570 -2.386837 -0.5861751 4e-04 0.44 0.0728 0.0307 0.0354 0.0078 0.0047 0.0100 -0.0022 0.0038 -0.005200012
2 -2.937649 -2.958624 -2.373960 -0.5636891 5e-04 0.44 0.0718 0.0323 0.0351 0.0075 0.0028 0.0095 -0.0019 0.0000 0.042085781
3 -2.984238 -2.937649 -2.428712 -0.5555258 2e-04 0.43 0.0728 0.0329 0.0347 0.0088 0.0018 0.0092 -0.0019 -0.0076 0.004577122
4 -2.976535 -2.970053 -2.443424 -0.5331107 9e-04 0.47 0.0588 0.0320 0.0331 0.0253 0.0011 0.0092 -0.0170 -0.0076 0.010515970
5 -2.979631 -2.962549 -2.468805 -0.5108256 6e-04 0.46 0.0613 0.0339 0.0333 -0.0005 -0.0006 0.0090 0.0060 -0.0058 0.058487141
6 -3.030536 -2.979631 -2.528079 -0.5024574 3e-04 0.43 0.0562 0.0333 0.0327 0.0109 -0.0006 0.0093 -0.0120 0.0000 -0.022896759
这是我的Train集,有300行。剩下的 700 行是测试集。我想要完成的是:
- 对于每一列拟合这种形式的线性模型:Y ~ X1。
- 使用创建的模型通过使用测试集的第一个 X1 获得 Y 的预测值。
- 之后,取Test set的第一行并rbind到Train set(现在Train set是301行)
- 使用测试集中 X1 的第 2 行预测 Y 的值。
- 对测试集的剩余 699 行重复上述操作。
- 将其应用于数据集 (X2,...,X14) 的所有剩余变量。
当我应用我为每个变量专门制作的代码时,我已经设法产生了准确的结果:
fittedvaluess<-NULL #empty set to fill
for(i in 1:nrow(TESTSET)){ #beggin iteration over the rows of Test set
TRAINSET<-rbind(TRAINSET,TESTSET[i,]) #add the rows to the train set
LM<-lm(Y~X1,TRAINSET) #fit the evergrowing OLS
predictd<-predict(LM,TESTSET[i+1,],type = "response") #get the predicted value
fittedvaluess<-cbind(fittedvaluess,predictd) #get the vector of the predicted values
print(cbind(i,length(TRAINSET$LHS),length(TRAINSET$DP),nrow(TRAINSET))) #to make sure it works
}
但是,我想自动执行此操作并在列上重复它。我做了这个:
data<-TRAINSET #cause every time i had to remake the trainset
fittedvaluesss<-NULL
for(i in 1:nrow(TESTSET){ #begin iteration on rows of Testset
data<-rbind(data,TESTSET[i,]) # rbind the rows to the Trainset called data
for(j in 1:ncol(TESTSET){ #iterate over the columns
LM<-lm(data$LHS~data[,j],data) #fit OLS
predictd<-predict(LM,TESTSET[i+1,j],type = "response") #get the predicted value
fittedvaluesss<-cbind(fittedvaluesss,predictd) #derive the predicted value
print(c(i,j)) #make sure it works
}
}
不幸的是,结果是错误的:拟合值是一个巨大的矩阵:
dim(fittedvaluesss)
[1] 2306 3167 #Stopped around the middle of its run
这没有任何意义。我什至 运行
i in 1:3
and
j in 1:3
而且矩阵仍然非常大。我试过从列开始迭代,然后遍历行。完全一样的错误结果。出于某种原因,在每个 运行 中,我从 PREDICT 函数中至少获得了 362 个值。我真的被这个问题困住了。
非常欢迎任何帮助。
编辑 1:这在金融中也称为递归预测方法。这是一种根据当前数据集的模型拟合预测未来值的方法。
考虑使用外循环中的列和内循环中的行来反转循环逻辑。此外,尝试使用 returns 结构比 for
循环更符合您的需求的嵌套应用函数。具体来说,内部 vapply()
return 是每个迭代列的所有测试集预测值的数值向量。然后外部 sapply()
将每个 returned 向量绑定到矩阵的一列。
最终,fittedvaluess
是一个维度为 TESTSET nrow X TESTSET ncol
的矩阵。还要注意,外循环省略了最后一列,因为您不会在 Y 上回归 Y。
fittedvaluess <- sapply(1:(ncol(TESTSET)-1), function(c){
col <- names(TESTSET)[[c]] # RETRIEVE COLUMN NAME FOR LM FORMULA
predictvals <- vapply(1:nrow(TESTSET), function(r){
TRAINSET <- rbind(TRAINSET, TESTSET[1:r,]) # BINDING ROWS ON AND PRIOR TO CURRENT ROW
LM <- lm(paste0("Y~", col), TRAINSET) # CONCATENATED STRING FORMULA
predictd <- predict(LM, TESTSET[r+1,], type="response")
}, numeric(1))
})
为什么要申请和申请?
sapply()
和 vapply()
都是 lapply()
的包装器。其中 sapply()
(simple lapply) 可以 return 向量或矩阵,vapply()
(verified lapply) 允许您专门选择 returned 输出——向量、列表、矩阵——以及类型和长度。所以 vapply
需要第三个参数来指定这样的标准。在这里,我们选择一个长度(或一个对象)的数值向量:numeric(1)
。由于这个预先指定,vapply()
在某些情况下往往 运行 比 lapply()
快。如果我们只选择一般 lapply()
,我们将需要 运行 列表输出的各种转换和转换以与矩阵输出对齐。在某种程度上,我们可以完成嵌套 vapply()
循环!
通过使用下面的代码,它是我原始代码的次要版本,除了我没有使用 predict
#EXPAND IT INTO DOING SO IN ALL COLUMNS
data<-TRAINSET
fittedvaluesss<-NULL
for(i in 1:nrow(TESTSET)){ #go each row
data<-rbind(data,TESTSET[i,]) #update the dataset
for(j in 1:ncol(TESTSET)){ #repead for each column the following
LM<-lm(data$LHS~data[,j]) #OLS reg
predictd<-coef(LM)[1]+coef(LM)[2]*TESTSET[i+1,j] #Simply apply the formula yourself A+Bx for each new iteration
#predict(LM,TESTSET[i+1,j],type = "response")
print(length(predictd)) #makes sure it is ONE value
fittedvaluesss<-c(fittedvaluesss,predictd)
print(c(i,j))
}
}
matrixa<-matrix(fittedvaluesss,15,648) #put the values in a matrix: Note that the Ypreds are in every row
matrixa<-t(matrixa) #transpose in order to have each Ypred from a var in a column
之所以可行,是因为每次迭代的预测函数 return 是一个大小为 361x15
的小矩阵( 在我的初始代码中 )和那是一次迭代。因此我放弃了预测功能并使用了系数本身。这似乎 return 是正确的预测。