Nneka
Nneka

Reputation: 1850

multiply every cell of a data.table by a different factor from a prespecified range

i have a data.table that i want to change:

  testDF <- data.table(col1 = c(1,1,1),
                       col2 = c(2,2,2),
                       col3 = c(3,3,3))

For specific columns, i want to multiply every row (and column) by a different factor. This factor has to satisfy some conditions:

  1. lie in a certain range, ex 0.5 - 1.5
  2. not to contain a specific number, ex. 1

for this i have written a function:

generateRandomFactor <- function(n){
  
  factor <- runif(n, 0.5, 1.5)
  if(any(factor == 1)){
    stop("factor of 1 chosen.")
  }
  
  return(factor)
  
}

the i use this function to multiply selected columns with a random factor:

SC <- c("col1", "col3")
factors <- generateRandomFactor(length(SC))
testMultiplication <- mapply(`*`, testDF[, ..SC], factors)

how can i extend this that the multiplication happens for selected columns, but also per row with a different factor every time? The number of rows is not known in advance. So, i essential want to create a new data.table with random contents of the same dimensions as a subset of the original data.table testDT[,..SC] and then multiply them together.

Or is there a better alternative?

Upvotes: 0

Views: 146

Answers (2)

Nneka
Nneka

Reputation: 1850

i ended up modifying the function:

generateRandomMatrix <- function(nrow,
                                 ncol){
  
  randomMatrix <- matrix(runif(nrow*ncol), nrow = nrow, ncol = ncol)

  if(any(randomMatrix == 1)){
    stop("factor of 1 chosen.")
  }
  
  return(randomMatrix)
  

}

and then multiply the data.tables:

  randomFactors <- generateRandomMatrix(nrow(testDF) , length(SC))
  testDF_mock <- testDF[, ..SC] * randomFactors

Upvotes: 0

ThomasIsCoding
ThomasIsCoding

Reputation: 101044

Maybe you can try the code below

testDF[, c(SC) := lapply(.SD[, SC, with = FALSE], function(x) x * runif(length(x), 0.5, 1.5))]

and you will see

        col1 col2     col3
1: 0.8953371    2 1.501498
2: 1.0371162    2 4.234734
3: 0.8999022    2 2.519295

Upvotes: 2

Related Questions