Reputation: 65
I have a large matrix (8,000 x 8,000) containing numerical data. I would like an output matrix with a single row containing the row index of the first element in each column to satisfy a logical operator. Note that not all the columns will have an element satisfying the condition.
Example input:
Column
Row 1 2 3 4
1 34.349 23.642 64.321 12.320
2 74.734 11.755 29.424 55.432
3 31.345 99.328 64.236 45.453
4 22.436 84.345 45.323 21.008
5 7.323 101.324 45.254 32.233
6 119.345 23.324 72.474 53.543
Logical operator: x > 70 gives an example output of:
Column
Row 1 2 3 4
1 2 3 6 NA
I'm new to R and struggled to get this output using the standard match and which functions.
Upvotes: 1
Views: 150
Reputation: 388907
Since, it is a matrix we can use apply
with margin = 2
(column-wise). Here we check if the column has at least one value greater than 70 and return it's index or else return NA.
apply(mat > 70, 2, function(x) if (any(x)) which.max(x) else NA)
#V1 V2 V3 V4
# 2 3 6 NA
Ideally apply(mat > 70, 2, which.max)
, would have given you what you need but it fails when you have no element greater than 70 hence, the check with if
and any
condition.
This would also work with dataframe.
In case there are no elements greater than 70 and column has NA
values, it returns an error.
mat[1, 4] <- NA
apply(mat > 70, 2, function(x) if (any(x)) which.max(x) else NA)
Error in if (any(x)) which.max(x) else NA : missing value where TRUE/FALSE needed
In such case, we can use na.rm
argument in any
to avoid this error.
apply(mat > 70, 2, function(x) if (any(x, na.rm = TRUE)) which.max(x) else NA)
#V1 V2 V3 V4
# 2 3 6 NA
Upvotes: 1