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.