Devon O'Rourke
Devon O'Rourke

Reputation: 247

obtaining max value in each column and printing associated column and row name

This post got me started, but I haven't been able to manipulate the expression to sufficiently generate the desired output. As a simplified version of the file contents, let's say I create the following matrix in R:

set.seed(14)
B = matrix(sample(1:100, 9),
      nrow=3,
      ncol=3)

colnames(B) <- c("sam1", "sam2", "sam3")
rownames(B) <- c("obs1", "obs2", "obs3")

It should look something like this:

        sam1    sam2    sam3
obs1    26      54      88
obs2    64      95      40 
obs3    94      49      45

What I'd like to be able to do is to loop through this matrix to calculate the maximum value in each column, then print out a new file which incorporates the value as well as the row name and column name. Thus the desired output would be a new file structured as follows:

sam1    94    obs3
sam2    95    obs2
sam3    88    obs1

If it helps, the file itself need not be a matrix. Rather, it could also be structured as a simple .csv file where obs are themselves are the first column (rather than rowname), and sam are elements across the first row (less the first column).

Thank you for your consideration

Upvotes: 1

Views: 427

Answers (3)

Onyambu
Onyambu

Reputation: 79188

data.frame(w=colnames(B),x=B[cbind(n<-max.col(B),1:ncol(B))],y=rownames(B)[n])
     w  x    y
1 sam1 94 obs3
2 sam2 95 obs2
3 sam3 88 obs1

Upvotes: 1

denis
denis

Reputation: 5673

with data.table you could do:

library(data.table)
B <- setDT(as.data.frame(B))
B[,name := c("obs1", "obs2", "obs3")]

B loks like

   sam1 sam2 sam3 name
1:   26   54   88 obs1
2:   64   95   40 obs2
3:   94   49   45 obs3

Then you simply melt and take the max value for each variable group

melt(B)[,.SD[value == max(value),.(value,name)],by = variable]

   variable value name
1:     sam1    94 obs3
2:     sam2    95 obs2
3:     sam3    88 obs1

Upvotes: 0

JBGruber
JBGruber

Reputation: 12410

@Onyambu beat me to the punch but here is my solution using apply:

C <- data.frame(row.names = colnames(B),
                    MaxVal = apply(B, 2, max),
                    WhichMax = apply(B, 2, which.max))
C
     MaxVal WhichMax
sam1     94        3
sam2     95        2
sam3     88        1

Upvotes: 1

Related Questions