4

I'm doing some analysis stuff and using R. I encountered a problem:

I have a list of logicals, which looks as follows :

list = (TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE)

for every logical value a have a list of numeric values :

num = (1, 4, 3, 7, 3, 2 , 23, 98, 5)

I would like to sum the values for the blocks of TRUEs and put them in the matrix or sth.

Just like that :

list[1] == TRUE and list[2] == TRUE and list[3] == TRUE so i'm calculating the sum : 1+4+3 = 8 so matrix[1,1] <- 8 and then omit list[4] and list[5] because it's FALSE and go to list[6], matrix[2,1] <- 2 ... and so on...

I have no idea how to extract those blocks of TRUEs. I hope you can help me somehow!

Machavity
  • 30,841
  • 27
  • 92
  • 100
Jagoda
  • 424
  • 1
  • 5
  • 18

2 Answers2

4

You could use rle and do something like:

myL = c(TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE)
num = c(1, 4, 3, 7, 3, 2 , 23, 98, 5)
X <- rle(myL)
Y <- rep(seq_along(X$lengths)[X$values], X$lengths[X$values])
tapply(num[myL], Y, sum)
  1   3   5 
  8   2 103 

Here, the first group of TRUEs sums to 8, the second group (one value) is 2, and the third group (98 and 5) sum to 103.


Alternatively, install my "SOfun" package from GitHub, which has a function called TrueSeq that would be useful for this.

Install it with:

library(devtools)
install_github("mrdwab/SOfun")

The function does this:

TrueSeq(myL)
# [1] 1 1 1 0 0 2 0 3 3

This allows you to simply do:

tapply(num, TrueSeq(myL), sum)
#   0   1   2   3 
#  33   8   2 103 

Or, even better, use the zero2NA argument in TrueSeq, like this:

tapply(num, TrueSeq(myL, zero2NA=TRUE), sum)
#   1   2   3 
#   8   2 103
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
1

To find these block you can use diff function like this:

vec = c(TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE)
c(vec[1]==TRUE,diff(vec))
## [1]  1  0  0 -1  0  1 -1  1  0

The block starts when there is 1 and you add elements until there are 0. -1 indicates where false block starts.

bartektartanus
  • 15,284
  • 6
  • 74
  • 102