0

I am trying to create a set of new vectors based on a rule, for a list of vectors. My input consists of 3 normal vectors (index, rfree, ret) and a list of several vectors (roll), all vectors being the same length. I want the new vectors to follow the rule: if index>roll -> ret, else rfree, so that the index is evaluated against the "k" number of roll vectors giving "k" new vectors that only consist of ret and rfree inputs. My current program doesn't work and I can't figure out why. The error message I get is

"Error in `*tmp*`[[j]] : subscript out of bounds"

But I can't really figure out why. Any help is greatly appreciated.

#Input:
roll <- list(runif(85),runif(85))
index <- runif(85)
rfree <- rnorm(85)
ret <- rnorm(85)

#Programe:
aret <- function(index, roll, ret, rfree, k=2){
  aret <- list()  
  for (j in seq(k))
    for (i in 1:length(ret)){
      if (roll[[j]][i]>index[i])(aret[[j]][i] <- ret[i])
      else(aret[[j]][i] <- rfree[i])
    }
}
Brian Diggs
  • 57,757
  • 13
  • 166
  • 188
user3248544
  • 53
  • 1
  • 8
  • 3
    `k=k` is not doing anything here. And, to fully answer your question, we will need to see some of your data. Specifically, `index, `roll`, `ret` and `rfree`. I assume what is happening is that `k` is longer than `aret` or `roll` so you see the error... use something like `dput` to include your data and take some time to [read about reproducible examples](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – Justin Feb 04 '14 at 15:00
  • It would be nice if you gave some examples of your vectors, so that we can understand you more clearly. Perhaps use `dput(roll)`, for example, so we can just cut and paste it into our browsers. – nograpes Feb 04 '14 at 15:00
  • Ok, I will have to come back once I've read up on dput. Sorry for the unclear question. – user3248544 Feb 04 '14 at 15:11
  • BTW is there a reason you need `aret` to be a list rather than a matrix of dimension `k` X `length(ret)` ? – Carl Witthoft Feb 04 '14 at 15:47
  • Not really, just thought that since the 'roll' was in a list it would be the easiest way – user3248544 Feb 04 '14 at 15:59

1 Answers1

1

This should do it, but I agree with @Carl, a matrix will be easier to manipulate here if all vectors are the same length

roll <- matrix(runif(170),ncol=2) #lets use a matrix instead
index <- runif(85) #index is your indicator variable when compared to roll
rfree <- rnorm(85) #assign if roll>index
ret <- rnorm(85) #assign if index>roll

#use vector operations when possible, for speed and readability. Look into
#sapply, lapply etc. Apply is useful for column/row operations in matrices
result<-apply(roll,2, function(x){  
   # we will use an anonymous function here for this, 
   #but you could define elsewhere if needed
   w<-index>x  # where is index larger than our roll entries
   x[w]<-ret[w] #assign the corresponding ret there
   x[!w]<-rfree[!w] #assign the corresponding rfree where appropriate
   x
 })
JPC
  • 1,891
  • 13
  • 29
  • Thanks alot, this is really appreciated! As you probably figured I'm quite new to R and still struggling with finding the "logical" way to tackle a problem. I will certainly try to read up on the tips given :) – user3248544 Feb 05 '14 at 08:52
  • No problem. I am not as experienced in R either, but hoping to learn more about it and share what little I have learned. What I have found to be the case with a lot of array-based languages (think Matlab, R, Numpy etc) is: avoid loops. These languages usually have constructs more akin to functional maps (http://en.wikipedia.org/wiki/Map_(higher-order_function) that are a) more readable and b) (usually) faster – JPC Feb 05 '14 at 13:51