Ferroao
Ferroao

Reputation: 3066

changing vector to string - special separator for last element

I'm trying to concatenate elements of a dynamically changing vector with commas and "and" as separators in a string. The problem is, when the character vector has only one element, I have an unwanted "and" before the string.

vec <-c("something")
vec <-c("something","something")
vec <-c("something","something","something") 

paste0(c(paste(head(vec, n=length(vec) -1), collapse = ", ") , 
         "and", paste(tail(vec, n=1) ) 
        ), 
      collapse= " ")

[1] " and something" # not what is expected
[1] "something and something" # ok
[1] "something, something and something" #ok

Upvotes: 4

Views: 1193

Answers (4)

user1420372
user1420372

Reputation: 2207

I had previously used an(other) existing function but can't remember which one, but this works perfectly and I always use knitr! Hoping I remember it in future.

knitr::combine_words(c("something"))

something

knitr::combine_words(c("something","something"))

something and something

knitr::combine_words(c("something","something","something"))

something, something, and something

Upvotes: 4

akrun
akrun

Reputation: 887951

We can use sub with paste

fPaste <- function(vec) sub(",\\s+([^,]+)$", " and \\1", toString(vec))


fPaste("something")
#[1] "something"

fPaste(c("something","something"))
#[1] "something and something"

fPaste(c("something","something","something") )
#[1] "something, something and something"

fPaste(c("something","something","something", "something") )
#[1] "something, something, something and something"

Upvotes: 7

R Yoda
R Yoda

Reputation: 8770

And yet another way:

i <- length(list)
if (i <= 1) {
  as.character(list)
} else {
  paste0(paste0(list[1:(i - 1)], collapse = ", "), " and ", list[i])
}

Upvotes: 1

csgillespie
csgillespie

Reputation: 60522

I think you need some logical to detect if your vector has more than one element, so something like:

## Note I've change list to x since its
## confusing, as it's actually a vector
if(length(x) > 1) " and " else ""

This gives

paste0(c(
  paste(x[-length(x)], collapse = ", ") , 
         if(length(x) > 1) " and " else "", 
         x[length(x)]
         ), collapse= "" )

Upvotes: 0

Related Questions