Ernie - 1 year ago 46

R Question

I want to set NA's in every element of a matrix where the value in a column is greater than or equal to the value of a given vector. For example, I can create a matrix:

`set.seed(1)`

zz <- matrix(data = round(10L * runif(12)), nrow = 4, ncol = 3)

which gives for zz:

`[,1] [,2] [,3]`

[1,] 8 5 7

[2,] 6 5 1

[3,] 5 10 3

[4,] 9 1 9

and for the comparison vector (for example):

`xx <- round(10L * runif(4))`

where xx is:

`[1] 6 3 8 2`

if I perform this operation:

`apply(zz,2,function(x) x >= xx)`

I get:

`[,1] [,2] [,3]`

[1,] TRUE FALSE TRUE

[2,] TRUE TRUE FALSE

[3,] FALSE TRUE FALSE

[4,] TRUE FALSE TRUE

What I want is everywhere I have a TRUE element I want an NA and everywhere I have a FALSE I get the number in the zz matrix (e.g., manually ...):

`NA 5 NA`

NA NA 1

5 NA 3

NA 1 NA

I can cobble together some "for" loops to do what I want, but is there a vector-based way to do this??

Thanks for any tips.

Answer Source

Here is one option to get the expected output. We get a logical matrix (`zz >= xx)`

, using `NA^`

on that returns NA for the TRUE values and 1 for the FALSE, then multiply it with original matrix 'zz' so that NA remains as such while the 1 changes to the corresponding value in 'zz'.

```
NA^(zz >= xx)*zz
# [,1] [,2] [,3]
#[1,] NA 5 NA
#[2,] NA NA 1
#[3,] 5 NA 3
#[4,] NA 1 NA
```

Or another option is `ifelse`

```
ifelse(zz >= xx, NA, zz)
```

```
zz <- structure(c(8, 6, 5, 9, 5, 5, 10, 1, 7, 1, 3, 9), .Dim = c(4L, 3L))
xx <- c(6, 3, 8, 2)
```