Home > database >  Indexing tables of logical vectors with zero counts in R
Indexing tables of logical vectors with zero counts in R

Time:03-30

I have the following:

> v1 <- c(T, F, T, T, F)
> table(v)
v
FALSE  TRUE 
    2     3 

To index the 'True' column, I do this:

> `table(v1)[2]`
TRUE 
   3 

However, if a logical vector contains only FALSE values, the table will only have one column and the previos strategy no longer works to retrieve the TRUE column:

> v2 <- c(F, F, F, F, F)
> table(v2)[2]
<NA> 
  NA 

How can one consistently index the TRUE column regardless of if its count is zero? One solution is to do this:

> table(factor(v2, levels= c("FALSE", "TRUE")))[2]
TRUE 
   0 

But this feels like cheating because it treats TRUE and FALSE as characters that become levels of a factor. For non-logical vectors, this behaviour is understandable, because there is no way of knowing what levels exist. (1) Is there a way to force table() to take into consideration the fact that logical vectors only take on two values and always present two columns for them? (2) Am I overthinking this and the last command is an acceptable and robust practice?

CodePudding user response:

Convert to factor with levels specified so that it always have two levels - without a TRUE value, there is no way the table to create the count of TRUE as that information is not present. With factor levels, it gives the TRUE count to be 0

table(factor(v2, levels = c(TRUE, FALSE)))[2]

It is not clear why a logical vector TRUE values needs to be counted with table and then extract based on the TRUE, FALSE names. It can be more easily done with sum as TRUE -> 1 and FALSE -> 0, negating (!) reverses this

> sum(v1)
[1] 3
> sum(!v1)
[1] 2
> sum(v2)
[1] 0
> sum(!v2)
[1] 5

CodePudding user response:

Because the case of logical is so specific for the requirements, I would write a specific function:

logitable <- function(x)
{
    x <- as.logical(x)

    kNA  <- sum(is.na(x))
    kT   <- sum(x, na.rm=TRUE)
    kF   <- length(x) - kT - kNA

    return (structure(
       c(kT, kF, kNA),
       names = c("TRUE", "FALSE", "NA")
    ))
}

Please note that the type of the return object is not of class "table" --- let me know if this is important to you, to return such an object.

Test with:

logitable(c(T,F,T,F,T))
logitable(c(T,T,T,T,T))
logitable(c(F,F,F,F,F))
logitable(c(T,F,T,F,NA))
  •  Tags:  
  • r
  • Related