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)