3

This is what I've got at the moment:

weights0 <- array(dim=c(nrow(ind),nrow(all.msim))) 
weights1 <- array(dim=c(nrow(ind),nrow(all.msim)))
weights2 <- array(dim=c(nrow(ind),nrow(all.msim)))
weights3 <- array(dim=c(nrow(ind),nrow(all.msim)))
weights4 <- array(dim=c(nrow(ind),nrow(all.msim)))
weights5 <- array(dim=c(nrow(ind),nrow(all.msim)))
weights0 <- 1 # sets initial weights to 1

Nice and clear, but not nice and short! Would experienced R programmers write this in a different way?

EDIT:

Also, is there an established way of creating a number of weights that depends on a pre-existing variable to make this generalisable? For example, the parameter num.cons would equal 5: the number of constraints (and hence weights) that we need. Imagine this is a common programming problem, so sure there is a solution.

RobinLovelace
  • 4,799
  • 6
  • 29
  • 40
  • possible dublicate: http://stackoverflow.com/questions/7519790/assign-multiple-new-variables-in-a-single-line-in-r – EDi Feb 25 '13 at 00:18
  • See your point but I think my question is more general. Perhaps I'm approaching it from the wrong angle in the first place by creating multiple objects. Could combine all the weights in a single object... Would you recommend trying this? – RobinLovelace Feb 25 '13 at 00:22
  • 3
    at the moment you are reassining the value `1` to weights 0, it is no longer an array, just an atomic vector of length 1. – mnel Feb 25 '13 at 00:28
  • 2
    If all your (2D) arrays have the same dimensions, you could just create one 3D array. – flodel Feb 25 '13 at 00:30
  • Sure but how? weights <- array(dim=c(nrow(ind),nrow(all.msim), num.cons)) looks good2me – RobinLovelace Feb 25 '13 at 00:32
  • 1
    @mnel's comment is right. You will want to use `weights0[] <- 1` – Ricardo Saporta Feb 25 '13 at 00:44

3 Answers3

9

Option 1

If you want to create the different elements in your environment, you can do it with a for loop and assign. Other options are sapply and the envir argument of assign

for (i in 0:5)
    assign(paste0("weights", i), array(dim=c(nrow(ind),nrow(all.msim))))

Option 2

However, as @Axolotl9250 points out, depending on your application, more often than not it makes sense to have these all in a single list

weights <-  lapply(rep(NA, 6), array, dim=c(nrow(ind),nrow(all.msim)))

Then to assign to weights0 as you have above, you would use

weights[[1]][ ] <- 1  

note the empty [ ] which is important to assign to ALL elements of weights[[1]]


Option 3

As per @flodel's suggestion, if all of your arrays are of the same dim, you can create one big array with an extra dim of length equal to the number of objects you have. (ie, 6)

weights <- array(dim=c(nrow(ind),nrow(all.msim), 6))

Note that for any of the options:

If you want to assign to all elements of an array, you have to use empty brackets. For example, in option 3, to assign to the 1st array, you would use:

weights[,,1][] <- 1
Ricardo Saporta
  • 54,400
  • 17
  • 144
  • 178
  • Yes, that looks like the best way of creating consecutively named weights - v. useful. I'm thinking that I should bunch all these objects into 1 now for max. simplicity though, as suggested by flodel – RobinLovelace Feb 25 '13 at 00:39
  • Your edit is v. useful. Any reason to have it as a list rather than an array. I'm ploughing on with weights <- array(dim=c(nrow(ind),nrow(all.msim),num.cons+1)), then weights[,,1] <- 1 # sets initial weights to 1 and seems to be working – RobinLovelace Feb 25 '13 at 00:47
  • 2
    @RobinLovelace, having it as lists allows for arrays of different sizes and classes. If they are all the same, then using flodel's suggestion is optimal. – Ricardo Saporta Feb 25 '13 at 00:50
  • That's correct, lists I find are a bit more forgiving regarding what you can put in each element. I work extensively with matrices of different sizes and I've gotten to the point now I always have to stop myself and think is there a better way than a list because it's become my automatic storage option of choice for this reason. – SJWard Feb 25 '13 at 14:34
6

I've just tried to have a go at achieving this but with no joy, maybe someone else is better than I (most likely!!). However I can't help but feel maybe it's easier to have all the arrays in a single object, a list; that way a single lapply line would do, and instead of referring to weights1 weights2 weights3 weights4 it would be weights[[1]] weights[[2]] weights[[3]] weights[[4]]. Future operations on those arrays would then also be achieved by the apply family of functions. Sorry I can't get it exactly as you describe.

SJWard
  • 3,629
  • 5
  • 39
  • 54
2

given what you're duing, just using a for loop is quick and intuitive

# create a character vector containing all the variable names you want..
variable.names <- paste0( 'weights' , 0:5 )

# look at it.
variable.names

# create the value to provide _each_ of those variable names
variable.value <- array( dim=c( nrow(ind) , nrow(all.msim) ) )

# assign them all
for ( i in variable.names ) assign( i , variable.value )

# look at what's now in memory
ls()

# look at any of them
weights4
Anthony Damico
  • 5,779
  • 7
  • 46
  • 77