Getting and removing the first character of a string

I would like to do some two-dimensional walks using character strings, assigning different values ​​to each character. I planned to β€œpop” the first character of the string, use it and repeat for the rest of the string.

How can I achieve something like this?

x <- 'hello stackoverflow' 

I would like to do something like this:

 a <- x.pop[1] print(a) 'h' print(x) 'ello stackoverflow' 
+62
string r
Oct 11 2018-11-11T00:
source share
6 answers

See ?substring .

 x <- 'hello stackoverflow' substring(x, 1, 1) ## [1] "h" substring(x, 2) ## [1] "ello stackoverflow" 



The idea of ​​having a pop method that returns a value and has the side effect of updating the data stored in x is a very concept from object oriented programming. Therefore, instead of defining a pop function for working with character vectors, we can make a reference class using the pop method.

 PopStringFactory <- setRefClass( "PopString", fields = list( x = "character" ), methods = list( initialize = function(x) { x <<- x }, pop = function(n = 1) { if(nchar(x) == 0) { warning("Nothing to pop.") return("") } first <- substring(x, 1, n) x <<- substring(x, n + 1) first } ) ) x <- PopStringFactory$new("hello stackoverflow") x ## Reference class object of class "PopString" ## Field "x": ## [1] "hello stackoverflow" replicate(nchar(x$x), x$pop()) ## [1] "h" "e" "l" "l" "o" " " "s" "t" "a" "c" "k" "o" "v" "e" "r" "f" "l" "o" "w" 
+102
Oct 11 2018-11-11T00:
source share

Use this function from stringi package

 > x <- 'hello stackoverflow' > stri_sub(x,2) [1] "ello stackoverflow" 
+8
Mar 14 '14 at 9:41
source share

substring definitely better, but here is one alternative to strsplit since I haven't seen it yet.

 > x <- 'hello stackoverflow' > strsplit(x, '')[[1]][1] ## [1] "h" 

or equivalent

 > unlist(strsplit(x, ''))[1] ## [1] "h" 

And you can paste leave the rest of the string together.

 > paste0(strsplit(x, '')[[1]][-1], collapse = '') ## [1] "ello stackoverflow" 
+6
May 13 '14 at 16:31
source share

There is also str_sub from the stringr package

 x <- 'hello stackoverflow' str_sub(x, 2) # or str_sub(x, 2, str_length(x)) [1] "ello stackoverflow" 
+4
May 25 '16 at 11:37
source share

delete first characters:

 x <- 'hello stackoverflow' substring(x, 2, nchar(x)) 

The idea is to select all characters, from 2 to the number of characters in x. This is important when you have an unequal number of characters in a word or phrase.

Choosing the first letter is trivial, as the previous answers:

 substring(x,1,1) 
+3
May 13 '14 at
source share

Another alternative is to use capture sub-expressions with the regmatches functions regmatches and regexec .

 # the original example x <- 'hello stackoverflow' # grab the substrings myStrings <- regmatches(x, regexec('(^.)(.*)', x)) 

This returns the entire string, the first character and a pop-up result in a list of length 1.

 myStrings [[1]] [1] "hello stackoverflow" "h" "ello stackoverflow" 

which is equivalent to list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))) . That is, it contains a super-set of desired elements, as well as a full line.




Adding sapply will allow this method to work for a character vector of length> 1.

 # a slightly more interesting example xx <- c('hello stackoverflow', 'right back', 'at yah') # grab the substrings myStrings <- regmatches(x, regexec('(^.)(.*)', xx)) 

This returns a list with a matching full string as the first item and corresponding subexpressions marked with () as the following items. Thus, in the regular expression '(^.)(.*)' , (^.) Matches the first character, and (.*) Matches the remaining characters.

 myStrings [[1]] [1] "hello stackoverflow" "h" "ello stackoverflow" [[2]] [1] "right back" "r" "ight back" [[3]] [1] "at yah" "a" "t yah" 

Now we can use the trusty sapply + [ method to pull the necessary substrings.

 myFirstStrings <- sapply(myStrings, "[", 2) myFirstStrings [1] "h" "r" "a" mySecondStrings <- sapply(myStrings, "[", 3) mySecondStrings [1] "ello stackoverflow" "ight back" "t yah" 
+1
Jun 12 '17 at 19:51 on
source share