Search code examples
r

Modify a user-defined function written in R


I have the following code written in R:

Gems <- data.frame(
  Color = c("Red", "Blue", "Purple", "Orange", 
            "Green", "Pink", "White", "Black", "Yellow"),
  Weight = round(runif(9,0.5,5),2),
  Value = round(abs(rnorm(9,0,5))+0.5,2)
)

InitilzePop <- function(size){
  pop <- (t(sapply(1:size, function(pop) round(runif(nrow(Gems),0, 1), 0))))
  colnames(pop)<- Gems$Color
  return(pop)
}

I want to change this part of the code round(runif(nrow(Gems),0, 1), 0) in a way that instead of generating outputs from random values, it takes values based on the size of Gems from a vector, for instance,

vector <- c(1,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,1,
            1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0)

I was wondering if it is possible to solve it without using base::sample(). Please consider the following:

myvector <- c(1,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0)

when calling InitilzePop(2) the output will be:

#>      Red Blue Purple Orange Green Pink White Black Yellow
#> [1,]   1    1      0      0     0    1     0     1      0
#> [2,]   0    1      1      1     0    0     0     0      1

And the vector will be: myvector <- c(1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0)

Hence, next time when calling InitilzePop(2) the output will be:

#>      Red Blue Purple Orange Green Pink White Black Yellow
#> [1,]   1    1      1      1    0    0     1     1      1
#> [2,]   0    0      1      1    1    0     0     1      1

And the vector will be: myvector <- c(1,0)


Solution

  • This will get you the described behavior. The global assignment, <<-, will modify myvector at each InitilzePop call. The desired matrices are more easily (and efficiently) built using the matrix function.

    Gems <- data.frame(
      Color = c("Red", "Blue", "Purple", "Orange", 
                "Green", "Pink", "White", "Black", "Yellow"),
      Weight = round(runif(9,0.5,5),2),
      Value = round(abs(rnorm(9,0,5))+0.5,2)
    )
    
    InitilzePop <- function(size) {
      n <- size*nrow(Gems)
      vec <- myvector[1:n]
      myvector <<- myvector[-1:-n]
      matrix(vec, size, nrow(Gems), TRUE, list(NULL, Gems$Color))
    }
    
    myvector <- c(1,1,0,0,0,1,0,1,0,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0)
    InitilzePop(2)
    #>      Red Blue Purple Orange Green Pink White Black Yellow
    #> [1,]   1    1      0      0     0    1     0     1      0
    #> [2,]   0    1      1      1     0    0     0     0      1
    myvector
    #>  [1] 1 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0
    InitilzePop(2)
    #>      Red Blue Purple Orange Green Pink White Black Yellow
    #> [1,]   1    1      1      1     0    0     1     1      1
    #> [2,]   0    0      1      1     1    0     0     1      1
    myvector
    #> [1] 1 0