How to Count True Values in a Logical Vector

How to count TRUE values in a logical vector

The safest way is to use sum with na.rm = TRUE:

sum(z, na.rm = TRUE) # best way to count TRUE values

which gives 1.

There are some problems with other solutions when logical vector contains NA values.

See for example:

z <- c(TRUE, FALSE, NA)

sum(z) # gives you NA
table(z)["TRUE"] # gives you 1
length(z[z == TRUE]) # f3lix answer, gives you 2 (because NA indexing returns values)

Additionally table solution is less efficient (look at the code of table function).

Also, you should be careful with the "table" solution, in case there are no TRUE values in the logical vector. See for example:

z <- c(FALSE, FALSE)
table(z)["TRUE"] # gives you `NA`

or

z <- c(NA, FALSE)
table(z)["TRUE"] # gives you `NA`

How to count number of TRUE values in a logical vector before FALSE

Here is a short way:

sum(cumprod(a))
# [1] 3

where cumprod gives a cumulative product (of zeros and ones in this case); so, it eliminates all TRUE's after the first FALSE, as in

cumprod(a)
# [1] 1 1 1 0 0 0

How to count logical values through multiple columns in R?

For each name you can sum the 'task' columns together.

library(dplyr)
df %>%
group_by(name) %>%
summarise(total = sum(unlist(select(cur_data(), starts_with('task'))), na.rm = TRUE))

# name total
#* <chr> <int>
#1 alex 1
#2 bill 2
#3 rob 3

How to count up all TRUE values from a column (of logical values) in a Data Frame?


set.seed(1L)
df1 <- data.frame(a1 = sample(c(TRUE, FALSE), 5, TRUE),
a2 = sample(c(TRUE, FALSE), 5, TRUE),
a3 = sample(c(TRUE, FALSE), 5, TRUE),
a4 = sample(c(TRUE, FALSE), 5, TRUE),
a5 = sample(c(TRUE, FALSE), 5, TRUE))

colSums(df1)
# a1 a2 a3 a4 a5
# 3 1 3 2 3

sum(df1[, 5])
# [1] 3

Count the number of consecutive TRUE values in R

This should work:

with(rle(x), sum(lengths[values] >= 2))

Explanation:

As you are using Booleans, you can take profit of it. rle(x)$lengths will return how many consecutive times TRUE or FALSE happen in the vector. Example

x <- c(T,F,T,T,T,F,T,F,T,F,T,T)
rle(x)$lengths
[1] 1 1 3 1 1 1 1 1 2

Now you only want those values in this vector that correspond to TRUEs. rle(x)$values returns a vector with the order of appearance. Example:

rle(x)$values
[1] TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE

You can use this to only get the TRUEs in the lengths vector:

rle(x)$lengths[rle(x)$values]
[1] 1 3 1 1 2

And the last step should be obvious: count how many of this values are grater or equal than 2. All together (with performance improvement):

with(rle(x), sum(lengths[values] >= 2))
[1] 2

How to count rows in a logical vector

Instead use sum. Though the safest option would be NROW (because it can handle both data.frams and vectors)

sum(complete.cases(source))
#[1] 2

Or alternatively if you insist on using nrow

nrow(source[complete.cases(source), ])
#[1] 2

Explanation: complete.cases returns a logical vector indicating which cases (in your case rows) are complete.


Sample data

source <- read.table(text = 
"185 2002-07-04 NA NA 20
186 2002-07-05 NA NA 20
187 2002-07-06 NA NA 20
188 2002-07-07 14.400 0.243 20
189 2002-07-08 NA NA 20
190 2002-07-09 NA NA 20
191 2002-07-10 NA NA 20
192 2002-07-11 NA NA 20
193 2002-07-12 NA NA 20
194 2002-07-13 4.550 0.296 20
195 2002-07-14 NA NA 20
196 2002-07-15 NA NA 20
197 2002-07-16 NA NA 20
198 2002-07-17 NA NA 20
199 2002-07-18 NA NA 20
200 2002-07-19 NA 0.237 20")

Count unique True/False for each variable

We can use lapply on the pattern vector (LETTERS[1:4]) and either specify the arguments of the function str_detect

sample[, LETTERS[1:4] := lapply(LETTERS[1:4], str_detect, string = product)]

Or use anonymous/lambda function

sample[, LETTERS[1:4] := lapply(LETTERS[1:4], function(x) 
str_detect(product, x))]

Then create the 'total_product' count as the row wise sum of logical vector i.e. TRUE -> 1 and FALSE -> 0

sample[, total_product := rowSums(.SD), .SDcols = A:D]

If we want to count the unique elements from 'product' for each 'customerid', an option is to split the column with strsplit, get the unique count with uniqueN

sample[, .(total_product = uniqueN(unlist(strsplit(product, 
'+', fixed = TRUE)))), by = customerid]

-output

#     customerid total_product
#1: 1 2
#2: 2 3
#3: 3 1
#4: 4 3
#5: 5 3
#6: 6 3
#7: 7 2

How to check if the value TRUE occurs consecutively for x number of times in R?

Keep logical values as logical, not string, and keep all your vectors in a list, then we can loop through them get the index where it meets the criteria, see example:

# example list of logical vectors 
l <- list(
v1 = c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE),
v2 = c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE),
v3 = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE))

# get index vector with 4 consequitive TRUE
ix <- sapply(l, function(i){
r <- rle(i)
any(r$lengths[ r$values ] >= 4)
})

#get the names of vectors
names(ix)[ ix ]
#[1] "v1" "v3"

# subset if needed
l[ ix ]
# $v1
# [1] TRUE TRUE TRUE FALSE TRUE FALSE TRUE TRUE TRUE TRUE
#
# $v3
# [1] TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE


Related Topics



Leave a reply



Submit