r-loops -` * tmp *`下标超出范围

时间:2014-07-18 17:41:41

标签: r subscript

我使用slove.QP来解决二次问题(资产分配问题)。我对不同的预期回报范围有四个限制。例如,对于从6.1到6.5的返回范围,我在这个范围内设置了一个约束,范围从6.6到7.0,我对它设置了另一个约束,等等。

我创建了一个约束矩阵,它看起来像这样:

min max min max min max min max
..  ..  ..  ..  ..  ..  ..  ..
..  ..  ..  ..  ..  ..  ..  ..
..  ..  ..  ..  ..  ..  ..  ..
..  ..  ..  ..  ..  ..  ..  ..
......

循环中的mincons包含约束矩阵的所有最小列,maxcons包含约束矩阵的所有最大列。

例如,对于第一个循环,预期返回范围从6.1到7.0,我在solve.QP函数中使用mincons [,1]和maxcons [,1]作为约束。同样的事情适用于接下来的三个循环。

但是R一直给我"下标超出范围"错误。我已经在stackoverflow上读了一些类似的问题,但我仍然无法弄清楚为什么我遇到了这个错误。任何人都可以帮助我。感谢。

You can download dataconstraints.csv and datacorrelations.csv at 
https://www.dropbox.com/s/6bosunahysdfpcj/dataconstraints.csv
https://www.dropbox.com/s/vb94obm83lttdej/datacorrelations.csv

library(quadprog)

mydata = read.csv("dataconstraints.csv") 
er <- matrix(mydata[,1], nrow=23, ncol=1)
stdevs <- matrix(mydata[,2], nrow=23, ncol=1) 
min <- mydata[,c(FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE)]
mincons <- as.matrix(sapply(min, as.numeric))
max <- -mydata[,c(FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE)]
maxcons <- as.matrix(sapply(max, as.numeric))

mycorr = read.csv("datacorrelations.csv")
correlation <- mycorr
b <- stdevs %*% t(stdevs)  
covariance <- b * correlation

dvec <- er
Dmat <- as.matrix(sapply(covariance, as.numeric))

A.Equality <- matrix(c(1), nrow=length(er), ncol=1)
Amat <- cbind(A.Equality, er, diag(length(er)),-diag(length(er)))

port_ret1 = NULL
bvec1 = matrix(data=NA, nrow=5, ncol=48)
w1 = matrix(data=NA, nrow=5, ncol=23)
sd1 = matrix(data=NA, nrow=5, ncol=1)
ret1 = matrix(data=NA, nrow=5, ncol=1)

port_ret2 = NULL
bvec2 = matrix(data=NA, nrow=5, ncol=48)
w2 = matrix(data=NA, nrow=5, ncol=23)
sd2 = matrix(data=NA, nrow=5, ncol=1)
ret2 = matrix(data=NA, nrow=5, ncol=1)

port_ret3 = NULL
bvec3 = matrix(data=NA, nrow=5, ncol=48)
w3 = matrix(data=NA, nrow=5, ncol=23)
sd3 = matrix(data=NA, nrow=5, ncol=1)
ret3 = matrix(data=NA, nrow=5, ncol=1)

port_ret4 = NULL
bvec4 = matrix(data=NA, nrow=5, ncol=48)
w4 = matrix(data=NA, nrow=5, ncol=23)
sd4 = matrix(data=NA, nrow=5, ncol=1)
ret4 = matrix(data=NA, nrow=5, ncol=1)

n <- (8.0-6.1)/0.1+1

for(i in 1:n){

  if(i>=1 & i<=5){
    port_ret1[i]<-6.1+0.1*(i-1)
    bvec1[i,] <- c(1, port_ret1[i], mincons[,1], maxcons[,1])
    w1[i,] <- solve.QP(Dmat, dvec, Amat, bvec1[i,], meq=1)$solution
    sd1[i,] <- sqrt(w1[i,] %*% Dmat %*% w1[i,])
    ret1[i,] <- w1[i,] %*% er
  }

  if(i>=6 & i<=10){
    port_ret2[i]<-6.1+0.1*(i-1)
    bvec2[i,] <- c(1, port_ret2[i], mincons[,2], maxcons[,2])
    w2[i,] <- solve.QP(Dmat, dvec, Amat, bvec2[i,], meq=1)$solution
    sd2[i,] <- sqrt(w2[i,] %*% Dmat %*% w2[i,])
    ret2[i,] <- w2[i,] %*% er
  }

  if(i>=11 & i<=15){
    port_ret3[i]<-6.1+0.1*(i-1)
    bvec3[i,] <- c(1, port_ret3[i], mincons[,3], maxcons[,3])
    w3[i,] <- solve.QP(Dmat, dvec, Amat, bvec3[i,], meq=1)$solution
    sd3[i,] <- sqrt(w3[i,] %*% Dmat %*% w3[i,])
    ret3[i,] <- w3[i,] %*% er
  }

  if(i>=16 & i<=20){
    port_ret4[i]<-6.1+0.1*(i-1)
    bvec4[i,] <- c(1, port_ret4[i], mincons[,4], maxcons[,4])
    w4[i,] <- solve.QP(Dmat, dvec, Amat, bvec4[i,], meq=1)$solution
    sd4[i,] <- sqrt(w4[i,] %*% Dmat %*% w4[i,])
    ret4[i,] <- w4[i,] %*% er
  }
}


Error in `[<-`(`*tmp*`, i, , value = c(1, 6.6, 0, 0, 0, 0, 0, 0, 0, 0,  : 
  subscript out of bounds

错误看起来像这样,所以我猜第二个if语句超出范围。如果我只运行第一个if语句,它运行正常,没有错误。我只是看不出任何出界问题。

1 个答案:

答案 0 :(得分:1)

好的,你的代码相当长,所以我没有通读并尝试理解它背后的概念,但我对你的for循环的内容进行了一些调整,并且它没有错误地执行。问题是,您的每个子组port_ret1通过port_ret4bvec1bvec4等等...都有索引长度为5,并且您尝试使用i = 1:20(因为n=20)索引其中的值。这适用于第一组 - port_ret1, bvec1, ...,但当您到达i=6时,您无法执行port_ret2[i] <- some value,因为port_ret2[6]不存在;即下标超出范围。所以我基本上只是将每个后续组中的i向后移动了适当的数量(仅在将其用作索引时,例如不在<-6.1+0.1*(i-1)中):

for(i in 1:n){
  ##
  if( i <= 5){

    port_ret1[i]<-6.1+0.1*(i-1)
    bvec1[i,] <- c(1, port_ret1[i], mincons[,1], maxcons[,1])
    w1[i,] <- solve.QP(Dmat, dvec, Amat, bvec1[i,], meq=1)$solution
    sd1[i,] <- sqrt(w1[i,] %*% Dmat %*% w1[i,])
    ret1[i,] <- w1[i,] %*% er
  } else if( i <= 10 ){

    port_ret2[i-5]<-6.1+0.1*(i-1)
    bvec2[i-5,] <- c(1, port_ret2[i-5], mincons[,2], maxcons[,2])
    w2[i-5,] <- solve.QP(Dmat, dvec, Amat, bvec2[i-5,], meq=1)$solution
    sd2[i-5,] <- sqrt(w2[i-5,] %*% Dmat %*% w2[i-5,])
    ret2[i-5,] <- w2[i-5,] %*% er
  } else if( i <= 15 ){

    port_ret3[i-10]<-6.1+0.1*(i-1)
    bvec3[i-10,] <- c(1, port_ret3[i-10], mincons[,3], maxcons[,3])
    w3[i-10,] <- solve.QP(Dmat, dvec, Amat, bvec3[i-10,], meq=1)$solution
    sd3[i-10,] <- sqrt(w3[i-10,] %*% Dmat %*% w3[i-10,])
    ret3[i-10,] <- w3[i-10,] %*% er
  } else {

    port_ret4[i-15]<-6.1+0.1*(i-1)
    bvec4[i-15,] <- c(1, port_ret4[i-15], mincons[,4], maxcons[,4])
    w4[i-15,] <- solve.QP(Dmat, dvec, Amat, bvec4[i-15,], meq=1)$solution
    sd4[i-15,] <- sqrt(w4[i-15,] %*% Dmat %*% w4[i-15,])
    ret4[i-15,] <- w4[i-15,] %*% er
  }
  ##
}

此外,您应该使用if...else if...else语句,而不是将冗余条件检查链接在一起的独立if语句。例如,在第二个声明中,您不必检查if(i >= 6 & i <= 10),因为当且仅当 i >= 6(因为您的第一个if(i <= 5)时,才会达到此条件条件)。无论如何,这确实执行没有错误,但就像我说的,我没有花时间从概念上理解它正在完成的任务,所以如果有其他东西需要调整,请告诉我。