-1

I have a multidimensional array (B_matrix) that I need to fill up with some random values. Since the dimension depends on two parameters K and C that are user defined, I cannot use nested loop to fill the array, so I have decided to fill it up recursively.

The problem with the recursion function (fillUp) is that that even though the array is declared outside the function, the array is set to NULL after the function is run.

B_dim = rep(2,((K+1+C)*2))
B_matrix = array( dim = B_dim, dimnames = NULL)  

string = c()
fillUp<-function(level, string ){
    if (level>=1){
        for(i in c(1,2)){
            Recall(level-1, c(string, i))     
        }
    }else{
        B_matrix[string] = 1; 
    }
}

fillUp(length(B_dim), string)

> sum( B_matrix == 1)
[1] NA

I'm new to R, so I'm not sure if the "global" declaration allows fillUp to change the values of the matrix.

Edit: Note that the line

B_matrix[string] = 1; 

is just a test case, and the original idea is to assign some random value that depends of the position of the array element.

Edit2:

Based on what @Bridgeburners hinted, I'm almost there. Replacing B_matrix[string] = 1, by

    assign('str', matrix(string,1), envir=.GlobalEnv)
    assign('hl', B_half_length,     envir=.GlobalEnv)
    rul <-runif(1, 0, sum(str[1:hl]))
    with(  .GlobalEnv,B_matrix[str] <- rul)

I get the error (last line):

Error in eval(expr, envir, enclos) : object 'rul' not found 

The problem, I guess, is that I'm working with variables from two different environments at the same time. I don't know how to proceed here.

This option doesn't work either

    assign('str',matrix(string,1),            envir=.GlobalEnv)
    assign('hl', B_half_length,               envir=.GlobalEnv)
    assign('ru', runif(1, 0, sum(str[1:hl])), envir=.GlobalEnv)
    with(  .GlobalEnv,B_matrix[str] <- ru)

Note: no visible binding for global variable 'ru'  

Edit3:

I've finally solved it:

    assign('str',matrix(string,1), envir=.GlobalEnv)
    with(   .GlobalEnv, B_matrix[str] <- runif(1, 0, sum(str[1:B_half_length])-B_half_length+1)   )

where B_half_length is a global variable

user3889486
  • 656
  • 1
  • 7
  • 21
  • What's the goal of this function (in words)? In R functions, you shouldn't attempt to modify objects outside the function scope; instead, you return modified objects from your function. I'm just having a hard time understanding the intent and desired output from this code. Please make a more fully [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – MrFlick Apr 23 '15 at 21:41
  • The idea is to fill the array with some random function whose parameter depends on the position of the array element, but if I cannot assign a constant value (1), I will not be able to go further... – user3889486 Apr 23 '15 at 21:45
  • I don't see why you think you need recursion here. Again, since this particular example isn't reproducible and there's no desired output to verify against, it's very hard to suggest "proper" alternatives. – MrFlick Apr 23 '15 at 21:47
  • Well If don't know the dimension before hand (ie values K and C), I cannot know the number of for loops I will need to fill up the array. If you have a better idea, I'm glad to hear it. Again I'm not filling up the array with a constant value. The desire output – user3889486 Apr 23 '15 at 21:51
  • I don't think you need looping either. Again. I have no idea what this function is supposed to do, so it is difficult to propose alternatives. We need a test case. – MrFlick Apr 23 '15 at 21:53
  • I just need to assign some random value depending on the position of the array (not implemented in the example). Example B_matrix[string] = uniform random value from 0 to sum(string[1:K]) – user3889486 Apr 23 '15 at 21:55

2 Answers2

1

Whenever a process is working within a function, it's working in a different environment. The object "B_matrix" is defined in the global environment. Since you're nesting environments (2*(K+C+1) times) you're not impacting the original object. If you simply replace line

B_matrix[string] = 1;

with

assign('str', matrix(string,1), envir=.GlobalEnv)
with(.GlobalEnv,B_matrix[str] <- 1)

your code will work. You simply need to specify which environment your expression is working in. (In the first line you're passing the local value of "string" to a global object named "str".)

Note, also, that indexing an array with a vector doesn't work. That is, "B_matrix[2,2,2,2,2,2]" is not the same as "B_matrix[c(2,2,2,2,2,2)]". But it works with a matrix

Bridgeburners
  • 637
  • 5
  • 15
0

What you want can be achieved with the following line code once you have initialised you B_matrix array:

B_matrix[] <- runif(length(B_matrix))
biostu
  • 121
  • 2