-1

Given the following string:

my.str <- "I welcome you my precious dude"

One splits it:

my.splt.str <- strsplit(my.str, " ")

And then concatenates:

paste(my.splt.str[[1]][1:2], my.splt.str[[1]][3:4], my.splt.str[[1]][5:6], sep = " ")

The result is:

[1] "I you precious"  "welcome my dude"

When not using the colon operator it returns the correct order:

paste(my.splt.str[[1]][1], my.splt.str[[1]][2], my.splt.str[[1]][3], my.splt.str[[1]][4], my.splt.str[[1]][5], my.splt.str[[1]][6], sep = " ")

[1] "I welcome you my precious dude"

Why is this happening?

Antsushi
  • 167
  • 10

2 Answers2

0

We can use collapse instead of sep

paste(my.splt.str[[1]], collapse= ' ')

If we use the first approach by OP, it is pasteing the corresponding elements from each of the subset

If we want to selectively paste, first create an object because the [[ repeat can be avoided

v1 <- my.splt.str[[1]]
v1[3:4] <- toupper(v1[3:4])
paste(v1, collapse=" ")
#[1] "I welcome YOU MY precious dude"

When we have multiple arguments in paste, it is doing the paste on the corresponding elements of it

paste(v1[1:2], v1[3:4])
#[1] "I you"      "welcome my"

If we use collapse, then it would be a single string, but still the order is different because the first element of v1[1:2] is pasteed with the first element of v1[3:4] and 2nd with the 2nd element

paste(v1[1:2], v1[3:4], collapse = ' ')
#[1] "I you welcome my"

It is documented in ?paste

paste converts its arguments (via as.character) to character strings, and concatenates them (separating them by the string given by sep). If the arguments are vectors, they are concatenated term-by-term to give a character vector result. Vector arguments are recycled as needed, with zero-length arguments being recycled to "".


Also, converting to uppercase can be done on a substring without splitting as well

sub("^(\\w+\\s+\\w+)\\s+(\\w+\\s+\\w+)", "\\1 \\U\\2", my.str, perl = TRUE)
#[1] "I welcome YOU MY precious dude"
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I know, but what if I want to have the 3rd or 4th elements to be upper case? E.g. `paste(my.splt.str[[1]][1:2], toupper(my.splt.str[[1]][3:4]), my.splt.str[[1]][5:length(my.splt.str[[1]])], collapse = " ")`. This would return nonsense as well. I am sorry but it also doesn't answer the question. – Antsushi May 19 '20 at 20:21
  • But he explained what is happening. I didn't understand that this is what you meant by `collapse`. Also, you assigned the list element a variable which is different from what is in my question. – Antsushi May 19 '20 at 20:38
0

paste is designed to work with vectors element-by-element. Say you did this:

names <- c('Alice', 'Bob', 'Charlie')
paste('Hello', names)

You'd want to result to be [1] "Hello Alice" "Hello Bob" "Hello Charlie", rather than "Hello Hello Hello Alice Bob Charlie".

To make it work like you want it to, rather than giving the different sections to paste as separate arguments, you could first combine them into a single vector with c:

paste(c(my.splt.str[[1]][1:2], my.splt.str[[1]][3:4], my.splt.str[[1]][5:6]), collapse = " ")
## [1] "I welcome you my precious dude"
MattB
  • 651
  • 3
  • 11