'How to collapse a column of logicals into TRUE FALSE TRUE... and create a new column with the original number of consecutive values?

I would like to create new data frames within a list, where TRUE and FALSE logicals alternate and in a new column the number about how often they showed up consecutively in the original dataframes within lists.

library(dplyr)
set.seed(94756)
mat1 <- matrix(sample(seq(-1,100, 0.11),50, replace = TRUE),ncol = 5) 
mat1 <- as_tibble(mat1)

mat2 <- matrix(sample(seq(-1,100, 0.11),50, replace = TRUE),ncol = 5)  
mat2 <- as_tibble(mat2)

mat3 <- matrix(sample(seq(-1,100, 0.11), 50,replace = TRUE),ncol = 5)  
mat3 <- as_tibble(mat3)

data <- list(mat1, mat2, mat3)

data1 <- purrr::map(data, ~tibble::add_column(., V1_logical = between(.$V2, 20, 60), .after = 'V1'))
r_pre <- lapply(data1, "[", 2)

That in the end I get an example like this:

$logical = TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE ...
$length = 2, 1, 3 (=marker), 2, 1, 3, 7...


Solution 1:[1]

Something like

bind_rows(r_pre, .id = "i") %>% group_by(i) %>% count(V1_logical)

?

# A tibble: 6 × 3
# Groups:   i [3]
  i     V1_logical     n
  <chr> <lgl>      <int>
1 1     FALSE          3
2 1     TRUE           7
3 2     FALSE          5
4 2     TRUE           5
5 3     FALSE          2
6 3     TRUE           8

You could also do this with map (and it might be a hair more efficient), but this seems to work ...

If you want the number of runs of TRUE/FALSE, e.g. that a vector {TRUE, TRUE, TRUE, FALSE, FALSE, TRUE} should result in a component (2, 2, 1) (numbers in consecutive runs of T/F), and assuming you want all of the results concatenated into a single tibble, try something like

rfun <- function(x) with(rle(x[[1]]), tibble(lengths, values))
purrr::map_dfr(r_pre, rfun)
# A tibble: 15 × 2
   lengths values
     <int> <lgl> 
 1       1 TRUE  
 2       1 FALSE 
 3       2 TRUE  
 4       1 FALSE 
...

If you want it as a list of three tibbles, just use purrr::map instead of map_dfr:

purrr::map(r_pre, rfun)
[[1]]
# A tibble: 6 × 2
  lengths values
    <int> <lgl> 
1       1 TRUE  
2       1 FALSE 
3       2 TRUE  
4       1 FALSE 
5       4 TRUE  
6       1 FALSE 

[[2]]
# A tibble: 7 × 2
  lengths values
    <int> <lgl> 
1       2 TRUE  
2       1 FALSE 
3       1 TRUE  
4       2 FALSE 
5       1 TRUE  
6       2 FALSE 
7       1 TRUE  

[[3]]
# A tibble: 2 × 2
  lengths values
    <int> <lgl> 
1       2 FALSE 
2       8 TRUE  

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1