[SOLVED] Why is strsplit not working with my character string?

Issue

I wanted to combine R’s rev() function and strsplit function to check if a string is a palindrome. My idea was to use strsplit() to split up my character string into individual letters and then use rev on the result to reverse the order of the letters. So, say:

a = "summer"

and we do:

b = strsplit(a,"")

We get:

[[1]]
[1] "s" "u" "m" "m" "e" "r"

Looks like it should work. But use rev on this:

rev(b)

and the output doesn’t change:

[[1]]
[1] "s" "u" "m" "m" "e" "r"

Now, I’ve narrowed down the answer to have something to do with the ‘[[1]]’, which I recognise as list notation. If we do:

c = strsplit(a,"")[[1]]

We get:

[1] "s" "u" "m" "m" "e" "r"

i.e. no ‘[[1]]’. Now, if we use rev(c) here, we get the desired result:

[1] "r" "e" "m" "m" "u" "s"

Similarly, if we have:

d = 1:10

and use rev(d), we get:

[1] 10  9  8  7  6  5  4  3  2  1

What both of the successful attempts have in common is the lack of list notation. Could anybody enlighten me as to how R is treating our initial character string and why using list notation with strsplit allows us to utlise rev properly?

Solution

What is happening here is that when you call rev(b), you are reversing a list which has just one element in it. That one element is a vector of characters. So the reverse operation just returns the same thing:

b <- strsplit(a, "")
rev(b)

[[1]]
[1] "s" "u" "m" "m" "e" "r"

However, when you access the first (and only) element of that list, you reverse the vector of letters:

rev(b[[1]])

[1] "r" "e" "m" "m" "u" "s"

If you take a list with more than one element and reverse it, you will see the elements reverse:

lst <- list(a=c("v", "x"), b=c("y", "z"))
lst

$a
[1] "v" "x"

$b
[1] "y" "z"

rev(lst)

$b
[1] "y" "z"

$a
[1] "v" "x"

Answered By – Tim Biegeleisen

Answer Checked By – Terry (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *