Reputation: 633
For the last 3 hours I am trying to vectorize some piece of code. The idea is to loop over a matrix and compare all the values with the mean over the columns. If the values are larger, set them to 999.
comparevalues <- function(y){
x <- apply(y,2, function(y) mean(y,na.rm=T))
for (j in 1:ncol(y)){
for (i in 1:nrow(y)){
if (!is.na(y[i,j]) & y[i,j] > x[j]) y[i,j] <- 999
}
}
return(y)
}
Testing, e.g. with:
m1 <- matrix(c(1:3,NA,2.4,2.8,3.9,0,1,3,0,2,1.3,2,NA,7,3.9,2.4),6,3)
comparevalues(m1)
results in:
[,1] [,2] [,3]
[1,] 1 999 1.3
[2,] 2 0 2.0
[3,] 999 1 NA
[4,] NA 999 999.0
[5,] 999 0 999.0
[6,] 999 999 2.4
My question is:
1) Can this kind of structure be vectorized, and if so, how can it be done?
2) I am trying to use apply
and similar functions in this context. Likely there are different ways to solve this, but for learning purpose, I'd appreciate if someone could address apply
as well. However if there are better ways I'd like to know them too.
Upvotes: 1
Views: 203
Reputation: 887048
We use the colMeans
to get the mean
of the columns of 'm1', replicate it using col(m1)
, check whether the 'm1' is greater than those value to get a logical matrix, extract the elements of 'm1' using that and assign it to 999.
m1[m1 >colMeans(m1, na.rm=TRUE)[col(m1)]] <- 999
m1
# [,1] [,2] [,3]
#[1,] 1 999 1.3
#[2,] 2 0 2.0
#[3,] 999 1 NA
#[4,] NA 999 999.0
#[5,] 999 0 999.0
#[6,] 999 999 2.4
Upvotes: 1