Kurt Ludikovsky
Kurt Ludikovsky

Reputation: 712

Logical Operation on Matrix/Vector

I have a two dimensional matrix with logical values (TRUE/FALSE).

What I need is a result-vector which represents the logical or of the elements of each row.

head(m1)
    Z1    Z2    Z3    Z4    Z5    Z6    ZZ
1  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
3 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
4 FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
5 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
6 FALSE FALSE  TRUE FALSE FALSE FALSE FALSE

the resulting vector (one dim matrix) should look like.

    RZ2   
1  TRUE 
2 FALSE 
3 FALSE 
4  TRUE 
5 FALSE 
6  TRUE 

As far is I understood, one option is to use the *apply function.

But which func-parameter to use there?

Upvotes: 2

Views: 1033

Answers (2)

Patrick Cree
Patrick Cree

Reputation: 39

Maybe something like this works:

df = data.frame(c(TRUE,FALSE, FALSE),c(TRUE,FALSE, FALSE),c(TRUE,FALSE, TRUE))
> sumdf = apply(df, MARGIN = 1, FUN = sum)
> sumdf[sumdf > 0] = 1
> sumdf
[1] 1 0 1

Upvotes: 1

akrun
akrun

Reputation: 887068

We can use rowSums to sum the TRUE values in each row. Then, we double negate (!!) to convert back to a logical vector such all elements that are not '0' will be TRUE and '0' gets coerced to FALSE.

v1 <- unname(!!rowSums(m1))
v1
#[1]  TRUE FALSE FALSE  TRUE FALSE  TRUE

Or another option is pmax if m1 is a data.frame. This will return 1 for TRUE if there is any TRUE in each row and 0 for only FALSE values. This can be converted back to logical vector (!=0).

v1 <- do.call(pmax, as.data.frame(m1))!=0
v1
#[1]  TRUE FALSE FALSE  TRUE FALSE  TRUE

Or we can loop through the rows using apply with MARGIN=1 with any as the FUN. It will return TRUE if there is any TRUE element or else FALSE.

v1 <- unname(apply(m1, 1, any))
v1
#[1]  TRUE FALSE FALSE  TRUE FALSE  TRUE

The above output vector can be converted to matrix

matrix(v1, ncol=1, dimnames=list(seq_along(v1), 'RZ2'))
#    RZ2
#1  TRUE
#2 FALSE
#3 FALSE
#4  TRUE
#5 FALSE
#6  TRUE

data

m1 <- structure(c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), .Dim = 6:7,
.Dimnames = list(
c("1", "2", "3", "4", "5", "6"), c("Z1", "Z2", "Z3", "Z4", 
"Z5", "Z6", "ZZ")))

Upvotes: 3

Related Questions