4

The base R functions paste and paste0 allow to concatenate strings (called "characters" in R).

For example:

new_people <- c(" R. A. Becker", "J. M. Chambers", "A. R. Wilks")
paste0("Hello ", new_people, "!")
# [1] "Hello  R. A. Becker!"  "Hello J. M. Chambers!" "Hello A. R. Wilks!" 

However, if one the arguments is of length zero (character()), it behaves inconsistent and unexpected:

new_people <- character()
paste0("Hello ", new_people, "!")
# [1] "Hello !"

This behavior is described (but not motivated) in ?paste:

Vector arguments are recycled as needed, with zero-length arguments being recycled to "". [...] Value: A character vector of the concatenated values. This will be of length zero if all the objects are, unless collapse is non-NULL in which case it is a single empty string.

If you do not find it "inconsistent" yet, imagine an answer to Equivalent of R's paste command for vector of numbers in Python that would really reproduce paste's behavior.

To avoid cluttering of my code I was searching for an alternative function or parameter for paste that would only recycle length 1 arguments. – Unfortunately, unsuccessfully. Not even the str_c function in @hadley's stringr package provides such behavior.

Is there an alternative to paste (and paste0) that behaves consistent w.r.t. zero length arguments (i.e. returns a zero length character vector in that case and an empty string if collapse is not NULL)?

jan-glx
  • 7,611
  • 2
  • 43
  • 63

2 Answers2

3

OUTDATED (still valid for R <4.0.1):


While writing this question, I found an almost satisfying answer:

new_people <- c(" R. A. Becker", "J. M. Chambers", "A. R. Wilks")
sprintf("Hello %s!", new_people)
# [1] "Hello  R. A. Becker!"  "Hello J. M. Chambers!" "Hello A. R. Wilks!"   

new_people <- character()
sprintf("Hello %s!", new_people)
# character(0)

This, however, lacks the nice linkage between the variables and their position in the string that paste has and requires an additional surrounding paste(..., collapse="") if one wants to smush the strings together.

jan-glx
  • 7,611
  • 2
  • 43
  • 63
2

In R 4.0.1 a new argument recycle0 was introduced to paste and paste0 (see NEWS) that does just that:

new_people <- character()
paste0("Hello ", new_people, "!", recycle0 = TRUE)
# character(0)

It also plays nicely with collapse=TRUE:

new_people <- character()
paste0("Hello ", new_people, "!", collapse = "\n", recycle0 = TRUE)
# ""

Currently the default is FASLE, I hope it will be gracefully changed to TRUE some day in the not too far future.

jan-glx
  • 7,611
  • 2
  • 43
  • 63