989
989

Reputation: 12937

Split string containing ordered numbers in R

I have strings like this:

"12385402763024590"

It contains numbers in alternating ascending and descending order. I would like to split them based on these orders. The output would be:

"1238"  "540"  "27"  "630"  "2459" "0"

How we can do that in R?

Upvotes: 0

Views: 148

Answers (3)

Chris S.
Chris S.

Reputation: 2225

You could also pass two vectors to substring

x <- "12385402763024590"
substring(x, c(1,5,8,10,13,17), c(4,7,9,12,16,17))
[1] "1238" "540"  "27"   "630"  "2459" "0" 

Maybe?

sp1 <- function(x){
   y <- as.numeric(strsplit(x, "")[[1]])
   n <- cumsum(rle(diff(y)<0)$lengths) +1
   substring(x, c(1, n[-length(n)]+1),   n )
}

sp1(x)
[1] "1238" "540"  "27"   "630"  "2459" "0" 

Upvotes: 2

989
989

Reputation: 12937

Here is my own solution using base R:

f <- function(r, char_s){
    cuts <- c(0, which(diff(r) != 1), length(r))
    sapply(seq_along(tail(cuts,-1)), function(x) 
                  paste0(char_s[r[(cuts[x]+1):cuts[x+1]]],collapse=""))
}

char_s <- strsplit(s, "")[[1]]
dif <- c(1,diff(as.numeric(char_s)))

# ascending orders
f(which(dif>0), char_s)
# [1] "1238" "27"   "2459"

# descending orders
f(which(dif<0), char_s)
# [1] "540" "630" "0" 

Upvotes: 1

akuiper
akuiper

Reputation: 214957

Here is an option using rleid from data.table package and the split function from base R:

library(data.table)
strToNum <- as.numeric(strsplit(s, "")[[1]])
# split the string into numeric vectors

sapply(split(strToNum, c(1, rleid(diff(strToNum) > 0))), paste0, collapse = "")
# calculate the rleid for sequence in ascending or descending order and split the vector 
# based on the run length encoding ID. Since the first element will always be classified 
# into the first sequence, we prepend 1 in the resulting rleid.

#      1      2      3      4      5      6 
# "1238"  "540"   "27"  "630" "2459"    "0" 

Upvotes: 2

Related Questions