Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R getting the minimum value for each row in a matrix, and returning the row and column name

I have a matrix like so:

enter image description here

Only in reality it is hundreds or thousands of values.

What I need to do is return the minimum value for each row, along with the row/col name.

So for row 1 in the example, "BAC", the minimum is 0.92 for BAC/CSCO, so I need to return something like:

BAC/CSCO 0.92

And then repeat this for each row in the matrix.

Assistance is greatly appreciated. I think apply is the trick, but I can't quite get the right combination.

like image 638
ctrlbrk Avatar asked Nov 26 '13 07:11

ctrlbrk


People also ask

How do I find the minimum value of a row in R?

min() in R The min() is a built-in R function that takes an object as an input and returns the minimum value out of it. To find the minimum value of vector elements, data frame, and columns, use the min() function.

How do you find the minimum element in a row of a matrix?

M = min( A ,[], dim ) returns the minimum element along dimension dim . For example, if A is a matrix, then min(A,[],2) is a column vector containing the minimum value of each row.

What is the command to find maximum and minimum values in a column row or matrix?

We have made use of the max() function which is used to find the maximum element present in an object. This object can be a Vector, a list, a matrix, a data frame, etc. The “which()” function is used to get the index or position of the value which satisfies the given condition.


2 Answers

X <- matrix(runif(20), nrow=4)
rownames(X) <- paste0("foo", seq(nrow(X)))
colnames(X) <- paste0("bar", seq(ncol(X)))

result <- t(sapply(seq(nrow(X)), function(i) {
  j <- which.min(X[i,])
  c(paste(rownames(X)[i], colnames(X)[j], sep='/'), X[i,j])
}))

print(X)
print(result)

will give you:

          bar1      bar2       bar3       bar4      bar5
foo1 0.2085419 0.6290522 0.12730378 0.17775105 0.3239684
foo2 0.8061464 0.7948392 0.09330563 0.06698921 0.5557932
foo3 0.1790950 0.7788139 0.35787944 0.39117325 0.2578457
foo4 0.9099254 0.4048508 0.54791272 0.38674301 0.3272156

and

     [,1]        [,2]                
[1,] "foo1/bar3" "0.127303782384843" 
[2,] "foo2/bar4" "0.0669892099685967"
[3,] "foo3/bar1" "0.179094966035336" 
[4,] "foo4/bar5" "0.327215566998348" 
like image 198
fotNelton Avatar answered Oct 22 '22 10:10

fotNelton


Or here with apply()

#CREATE THE DATA
df<-data.frame(matrix(data=round(x=rnorm(100,10,1),digits=3),nrow=10),
           row.names=c("A","B","C","D","E","F","G","H","I","J"))
colnames(df)<-c("AD","BD","CD","DD","ED","FD","GD","HD","ID","JD")

#RUN THROUGH THE DF
mins<-apply(df,2,function(x)return(array(which.min(x))))
mins<-data.frame(col=names(mins),row=mins)
df$mins<-apply(mins,1,FUN=function(x)return(paste(x["col"],
                                     rownames(df[as.numeric(x["row"]),]),
                                     df[as.numeric(x["row"]),x["col"]],
                                     sep="/")))
> df
      AD     BD     CD     DD     ED     FD     GD     HD     ID     JD       mins
A  9.292 11.568 10.489  9.512  7.755  8.545  9.989  9.660  9.240  9.913 AD/G/8.477
B 11.972 11.297  9.221 10.936  8.665  9.154 10.620  8.335 11.149 11.382 BD/F/7.588
C  9.910  9.762 11.744  8.938 11.283  8.750  8.719 10.929  9.158 10.168 CD/G/8.481
D  9.986  8.776  9.922  9.016 10.691 10.667  9.876 11.417 10.391 10.823 DD/C/8.938
E  8.877  9.672  9.024 10.424  9.033  8.709 10.176  9.937 10.891  9.779 ED/A/7.755
F  8.656  7.588 10.071  9.549  8.654  7.965 11.693  9.019  8.665  8.971 FD/F/7.965
G  8.477  9.686  8.481 10.925 11.034 12.021 10.642 11.087 10.398  9.989 GD/C/8.719
H  9.578 11.660 10.864  9.801  9.188 11.006 11.282 10.139  9.888  8.775 HD/B/8.335
I 11.361 10.131 10.502 11.195 11.802 10.817 10.141  9.614 10.676  7.404 ID/F/8.665
J 11.754 11.096  9.645 10.496 11.772  9.336  8.887 11.124  9.211 11.169 JD/I/7.404    
like image 27
Troy Avatar answered Oct 22 '22 08:10

Troy