Reputation: 12937
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
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
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
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