# Subset array conditional on boolean

Hi, I am trying to subset a 2d array conditional on a boolean.

I can do it using filter and [] with 1d arrays like:

``````X = randn(100);
filter(a->a>=0,X)
``````

However, suppose I have something like:

``````X = randn(100);
Y = 3 .* randn(100) .+ 2;
S = X .>= 0;
data = [X Y S];
``````

And I want to create two new arrays called `data0` and `data1` where the first contains X, Y, S when S == 0, and the latter when S == 1. `filter` doesn’t seem to work. What is the best way to do it?

Hi,
I’m not sure why you would want to save `S` into your new data matrix, since it will be all `1` or `0`
but one thing you could do is the following:

``````X = randn(100);
Y = 3 .* randn(100) .+ 2;
S = X .>= 0;
X_greater_0 = X[S]
X_smaller_0 = X[ .!S]

data0 = [ X_greater_0 Y[  S]  ones(100) ]
data1 = [ X_smaller_0 Y[.!S]  zeros(100)]
``````

The relevant entry in the docs is Logical Indexing.

2 Likes

Thanks Jnaslsensee. I still have some questions though. I implemented your code as

``````X = randn(100);
Y = 3 .* randn(100) .+ 2;
S = X .>= 0;

data0 = [ X[ S] Y[  S] ]
data1 = [ X[ .!S] Y[.!S] ]
``````

I don’t really need S to be in the data matrix, I just put it there. However, I tried doing something like `data0 = data[ S]` and it didn’t work. What if I have an arbitrarily large number of 1d arrays that I want to subset according to one boolean array, is there any better way to do this rather than `data0 = [A[ S] (…) Z[ S]]?

You could also do the following:

``````data = [ X Y ]
data0 = data[ S , : ]
data1 = data[ .!S, : ]
``````

This first copies your `X` and `Y` into a `data` matrix.
Then you use the logical indexing ( `S` ) for the first index and `:` for the second index, meaning take all.

This introduces a little more copying of data but as long as your code is not performance critical, it shouldn’t be a problem.

2 Likes