Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse only alphabetical patterns in a string in R

I'm trying to learn R and a sample problem is asking to only reverse part of a string that is in alphabetical order:

String: "abctextdefgtext"    
StringNew: "cbatextgfedtext"

Is there a way to identify alphabetical patterns to do this?

like image 440
S_B_3 Avatar asked Apr 13 '17 13:04

S_B_3


2 Answers

Here is one approach with base R based on the patterns showed in the example. We split the string to individual characters ('v1'), use match to find the position of characters with that of alphabet position (letters), get the difference of the index and check if it is equal to 1 ('i1'). Using the logical vector, we subset the vector ('v1'), create a grouping variable and reverse (rev) the vector based on grouping variable. Finally, paste the characters together to get the expected output

v1 <- strsplit(str1, "")[[1]]
i1 <- cumsum(c(TRUE, diff(match(v1, letters)) != 1L))
paste(ave(v1, i1, FUN = rev), collapse="")
#[1] "cbatextgfedtext"

Or as @alexislaz mentioned in the comments

 v1 = as.integer(charToRaw(str1))
 rawToChar(as.raw(ave(v1, cumsum(c(TRUE, diff(v1) != 1L)), FUN = rev))) 
 #[1] "cbatextgfedtext"

EDIT:

1) A mistake was corrected based on @alexislaz's comments

2) Updated with another method suggested by @alexislaz in the comments

data

str1 <- "abctextdefgtext"
like image 101
akrun Avatar answered Nov 20 '22 10:11

akrun


You could do this in base R

vec <- match(unlist(strsplit(s, "")), letters)
x <- c(0, which(diff(vec) != 1), length(vec))
newvec <- unlist(sapply(seq(length(x) - 1),  function(i) rev(vec[(x[i]+1):x[i+1]])))
paste0(letters[newvec], collapse = "")

#[1] "cbatextgfedtext"

Where s <- "abctextdefgtext"

  1. First you find the positions of each letter in the sequence of letters ([1] 1 2 3 20 5 24 20 4 5 6 7 20 5 24 20)
  2. Having the positions in hand, you look for consecutive numbers and, when found, reverse that sequence. ([1] 3 2 1 20 5 24 20 7 6 5 4 20 5 24 20)
  3. Finally, you get the letters back in the last line.
like image 44
989 Avatar answered Nov 20 '22 09:11

989