Count occurrences

I have the following problem. I want to count the number of occurrences of values ​​that are less than or equal to zero. An example in the following data: 3 cases 1 (0,0,0), 2 (-1, -2), 3 (0,0). Is there a built-in function in R for counting sequential events.

a <- c(2,4,5,3,2,4,7,0,0,0,4,3,2,-1,-2,3,2,0,0,4)
+4
source share
5 answers

You can use rle:

> sum(rle(a<=0)$values)
[1] 3

Explanation:

rlesplits the vector into runs that> 0 or <= 0. $valuesare either true, or falsedepending on whether the corresponding run satisfies the predicate ( a <= 0), or its negation. You want the runs to match the value true, the function summakes them trueequal to 1.

+5

:

sum(rle(a <= 0)$values)

:

[1] 3

:

  • rle a <= 0.
  • rle(a <= 0):

    Run Length Encoding
      lengths: int [1:7] 7 3 3 2 2 2 1
      values : logi [1:7] FALSE TRUE FALSE TRUE FALSE TRUE ...
    
  • rle -:

    > sum(rle(a <= 0)$values)
    [1] 3
    
+6

( ) rleid

library(data.table)
uniqueN(rleid(a<=0)[a<=0])
#[1] 3

rleid (a <=0), ([a<=0]) length unique uniqueN


a base R

sum(diff(a <=0)==1)
#[1] 3
+1

rle , :

b <- a <= 0
sum(b) - sum(b[which(b) - 1])

, ( .)

I did a quick test and found that it runs several times faster for large vectors (from 10 million to 300 million elements).

v1 <- function(a) sum(rle(a<=0)$values)

v2 <- function(a) {
  b <- a <= 0
  sum(b) - sum(b[which(b) - 1])
}

v1.time <- NULL
v2.time <- NULL
sizes <- 1:30 * 1E7
for (s in sizes) {
  x <- sample(-100:100, s, replace = TRUE)

  v1.time <- c(v1.time, system.time(
    v1.result <- v1(x)
  )[['elapsed']])

  v2.time <- c(v2.time, system.time(
    v2.result <- v2(x)
  )[['elapsed']])

  print(c(v1.result, v2.result)) # Show that they agree
  print(v1.time)
  print(v2.time)
}

library(tidyverse)
data.frame(VectorSize = sizes,
           v1 = v1.time,
           v2 = v2.time) %>%
  gather('Version', 'Time', -VectorSize) %>%
  ggplot(aes(x = VectorSize, y = Time, color = Version)) + geom_point() + geom_smooth()

enter image description here

+1
source

In this example, how do I count all occurrences in all replicas?

set.seed(3)
b<-c(4,6,4,2,3)
run<- replicate(2,{
a <- runif(5,3,5)
dif <- a - b
return(dif)
})
run
 [,1]       [,2]
[1,] -0.6639169  0.2087881
[2,] -1.3849672 -2.7507331
[3,] -0.2301153 -0.4107982
[4,]  1.6554686  2.1552198
[5,]  1.2042013  1.2619585

When i try

sum(rle(run<=0)$values)

I get

Error in rle(run <= 0) : 'x' must be a vector of an atomic type

but he works with

uniqueN(rleid(run<=0)[run<=0])
0
source

Source: https://habr.com/ru/post/1670874/


All Articles