Home > Blockchain >  Function to count of consecutive digits in a string vector
Function to count of consecutive digits in a string vector

Time:12-31

I would like to create a function that takes a string object of at least 1 element and contains the numbers 2 through 5, and determine if there are consecutive digits of at least N length where N is the actual digit value.

If so, return the string true, otherwise return the string false.

For Example:

Input: "555123" 
Output: false

Because 5 is found only 3 times instead of 5.

Or:

Input: "57333" 
Output: true

Because 3 is found exactly 3 times.

CodePudding user response:

Try rle strsplit if you are working with base R

f <- function(s) {
  with(
    rle(unlist(strsplit(s, ""))),
    any(as.numeric(values) <= lengths & lengths > 1)
  )
}

and you will see

> f("555123")
[1] FALSE

> f("57333")
[1] TRUE

CodePudding user response:

Late to the party but maybe still worth your while:

Data:

x <- c("555123", "57333", "21112", "12345", "22144", "44440")

Define vector with allowed numbers:

digits <- 2:5

Define alternation pattern with multiple backreferences:

patt <- paste0("(", digits, ")\\", c(1, digits), "{", digits - 1, "}", collapse = "|")

Input patt into str_detect:

library(stringr)
str_detect(x, patt)
[1] FALSE  TRUE FALSE FALSE  TRUE  TRUE

CodePudding user response:

You could check if the values in table correspond to the names.

x <- c('555123', '57333')

f <- \(x) {
  s <- strsplit(x, '')
  lapply(s, \(x) {
    tb <- table(x)
    names(tb) == tb
    }) |> setNames(x)
}

f(x)
# $`555123`
# x
#    1     2     3     5 
# TRUE FALSE FALSE FALSE 
# 
# $`57333`
# x
#    3     5     7 
# TRUE FALSE FALSE 

CodePudding user response:

Run length encoding function rle can be used to count consecutive occurrences of values in a string, using the any function to see if any of the queried lengths is met.

f <- function(s){
  ff = Vectorize(\(x, i) any(x$lengths[x$values == i] >= i), "i")
  s = rle(strsplit(s, "")[[1]])
  any(ff(s, 2:5))
}

f("555123")
[1] FALSE
f("57333")
[1] TRUE

CodePudding user response:

Another way would be:

my_func <- function(x) {
  
  as.numeric(unlist(strsplit(x, ""))) -> all
  table(all[all %in% 2:5]) -> f 
  any(names(f) == f)
  
}

# Input <- "555123"
# (my_func(Input))
# FALSE

# Input <- "57333" 
# (my_func(Input))
# TRUE
  • Related