Home > other >  Divide each column of a matrix to its colSums if it is not zero without loop for a huge matrix
Divide each column of a matrix to its colSums if it is not zero without loop for a huge matrix

Time:12-20

I have a huge matrix and I need to divide each column of it to its sum (if it is not zero). I have used a loop but since the matrix is very big, it takes a long time to do it.

sum_D<- colSums(R_t)
  for(i in 1:NR){
    if(sum_D[i]>0){
      R_t[,i]<-c(as.numeric(R_t[,i])/sum_D[i]) 
    }
  } 

then I have write this code but its result is not a matrix.

 matrixp<- apply(X=R_1, MARGIN=2, FUN=ColpSum)
ColpSum<-function(x){
  x<-as.matrix(x)
  if(colSums(x)==0){
    return(0)
  }
  else{
    return(x/colSums(x))
  }
}

How can I solve the problem?

For example:

|1|2|3|4|
|:----|:----|:----|:----|
|2|0|0|0|
|0|1|0|0|
|0|1|0|0|

results:

|1|2|3|4|
|:----|:----|:----|:----|
|1|0|0|0|
|0|0.5|0|0|
|0|0.5|0|0|

CodePudding user response:

data:

test_matrix <- matrix(c(1,2,3,0,0,0,3,2,1),nrow=3)

base R approach:

ColSum2<-function(x){
  #x<-as.matrix(x)
  if(sum(x)==0){
    return(1)
  }
  else{
    return(sum(x))
  }
}

sum_value <- apply(test_matrix,2,ColSum2)
t(t(test_matrix)/sum_value)

data.frame approach:

ColpSum<-function(x){
  #x<-as.matrix(x)
  if(sum(x)==0){
    return(0)
  }
  else{
    return(x/sum(x))
  }
}
library(dplyr)
test_matrix%>%as.data.frame()%>%mutate_all(ColpSum)%>%as.matrix()

CodePudding user response:

x        <- matrix(c(2,0,0,0,1,1,0,0,0,0,0,0), nrow = 3L)
cs_x     <- colSums(x)
cols2div <- which(cs_x > 0)

x[, cols2div] <- vapply(cols2div, \(i) x[, i] / cs_x[i], numeric(nrow(x)))

     [,1] [,2] [,3] [,4]
[1,]    1  0.0    0    0
[2,]    0  0.5    0    0
[3,]    0  0.5    0    0

CodePudding user response:

I would use sweep() and then replace NAs, i.e.

m3 <- sweep(m2, 2, colSums(m2), '/')
m3[] <- replace(m3, is.na(m3), 0)


     [,1] [,2] [,3] [,4]
[1,]    1  0.0    0    0
[2,]    0  0.5    0    0
[3,]    0  0.5    0    0

DATA

structure(c(2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0), dim = 3:4)

CodePudding user response:

if m is your matrix:

cs <- colSums(m)
cs[cs == 0] = 1
apply(m, 2, \(row) row/cs)
  • Related