Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

max.col with NA removal

Tags:

r

max

na

I'm looking to find the columns of matrix row-maxima while ignoring NAs. E.g.,

set.seed(1)
a <- matrix(runif(15), ncol=3)
a[a<.3] <- NA
a[5,] <- NA

That is:

> a
      [,1]  [,2]  [,3] 
[1,]    NA 0.898    NA 
[2,] 0.372 0.945    NA
[3,] 0.573 0.661 0.687
[4,] 0.908 0.629 0.384
[5,]    NA    NA    NA

The row maxima, ignoring NAs, can be obtained using max:

> apply(a, 1, max, na.rm=T)
[1] 0.898 0.945 0.687 0.908  -Inf

I'm looking for the column positions of these maxima, but max.col only works for rows without any NAs.

> max.col(a, ties.method="first")
[1] NA NA  3  1 NA

How could I find the columns of (first) maximizers for the rows with some non-missing values? I.e., something like:

[1]  2  2  3  1 NA
like image 712
dzeltzer Avatar asked Sep 01 '16 15:09

dzeltzer


1 Answers

We replace the 'NA' with -Inf in 'a' and apply the max.col on that.

v1 <- max.col(replace(a, is.na(a), -Inf), ties.method="first")

But, this will return 1 for the last row which have all NAs. To return NA, we can multiply it with the NA converted negated (!) rowSums of logical matrix (!is.na(a)).

v1 * NA^!rowSums(!is.na(a))
#[1]  2  2  3  1 NA

EDIT: Changed the replacement from 0 to -Inf based on @Frank's comment


As the OP was using apply, which.max can return the column index

apply(a, 1, function(x) which.max(x)[1])
#[1]  2  2  3  1 NA

Or

sapply(apply(a, 1, which.max), `length<-`, 1)
#[1]  2  2  3  1 NA
like image 160
akrun Avatar answered Sep 19 '22 09:09

akrun