简体   繁体   中英

Adding Gaussian noise to each element of rows of a matrix efficiently

I have a matrix m :

set.seed(1)
m = matrix(rnorm(100), nrow = 10, ncol = 10) # my data is not a random matrix in reality, but it should not matter

I want to add 5% Gaussian noise to each row of the matrix. Each element of a row of the matrix should get a different random noise. The random values should be calculated row-wise, based on the sd of each row.

So far, I have implemented it with a for loop and it seems to do the job:

for (i in 1:nrow(m)){
        m[i, ] = m[i, ] + rnorm(n = ncol(m), mean = 0, sd = sd(m[i, ]) * 0.05)
}

However, my real data is very large and I want to vectorize this implementation as much as possible.

One way would be like this...

#calculate the sd for each row...
sds <- apply(m, 1, sd)

#generate all noise factors at once and just add to m...
m <- m + rnorm(nrow(m) * ncol(m), mean = 0, sd = sds * 0.05)

This works because sds will be recycled for each column. In general these matrix operations are very fast in R.

This sould do the trick:

require(tidyverse)

set.seed(1)
m = matrix(rnorm(9), nrow = 3, ncol = 3)

> m
           [,1]       [,2]      [,3]
[1,] -0.6264538  1.5952808 0.4874291
[2,]  0.1836433  0.3295078 0.7383247
[3,] -0.8356286 -0.8204684 0.5757814

Calculate sd by row

m_sd <- apply(m, 1, sd)

Calculate noise by row and put it in a matrix

m_noise <- map(m_sd, rnorm, n = nrow(m), mean = 0) %>% 
  unlist %>% 
  matrix(nrow = 3, ncol = 3, byrow = TRUE)

Add original and noise matrix

m + m_noise * 0.05

> m + m_noise * 0.05
           [,1]       [,2]      [,3]
[1,] -0.6434161  1.6792503 0.5090823
[2,]  0.1747117  0.2976669 0.7544979
[3,] -0.8374496 -0.8211245 0.6140321

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM