I'm trying to work out a way of subsetting a matrix which is purely numeric (i.e. no column/row names). To put this in the form of a worked example, I would like to drop rows that do not meet a logical condition.
set.seed(42)
m <- matrix(sample.int(100, 10*10, TRUE), 10, 10)
Say I want to make a subset so I keep rows where the maximum row value is 90 or over, but drop those which do not meet this condition.
The only way I can think of doing this is through an if/else loop (max(m[i,]) > 90) but I feel there must be a more elegant way of doing this.
Any ideas?
You can simply create a logical matrix using m >= 90. That is possible because > is generic function with a matrix method (see ?S4groupGeneric for other functions with similar behaviour). Then, we can just run rowSums over it and check that the condition applies, for example
m[rowSums(m >= 90) > 0, ]
That means that if any value is equal or higher than 90, for sure the maximum is higher too- so no need to look for the maximum in the first place.
An alternative option is to use the very efficient matrixStats package and its rowMaxs function
library(matrixStats)
m[rowMaxs(m) >= 90, ]
As per your comments, here a possible vectorized range solution
Maxima <- rowMaxs(m)
m[Maxima >= 90 & Maxima <= 97, ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With