String concatenation can be done with paste, paste0, sprintf, or .Internal(sprintf).

sprintf vs paste

There’s not much difference in performance among these options.

x = 3
y = 5.7
microbenchmark(paste0("The value of x is ", x, " and y is ", y, "."),
               sprintf("The value of x is %s and y is %s.", x, y),times = 1000, unit = 's')
## Unit: seconds
##                                                   expr       min        lq
##  paste0("The value of x is ", x, " and y is ", y, ".") 3.397e-06 3.562e-06
##     sprintf("The value of x is %s and y is %s.", x, y) 3.455e-06 3.657e-06
##          mean    median         uq        max neval
##  5.913164e-06 3.735e-06 6.7165e-06 3.0814e-04  1000
##  5.663992e-06 3.804e-06 7.0105e-06 7.9754e-05  1000

sprintf vs .Internal(sprintf)

Replacing sprintf by .Internal(sprintf) results in a small gain in performance, which can turn out to be significant if the operation is repeated a lot.

sprintf("Annie eats %d apples in %.2f minutes, %d oranges in %.2f minutes", 4,5.2,7,7.3)
## [1] "Annie eats 4 apples in 5.20 minutes, 7 oranges in 7.30 minutes"
.Internal(sprintf("Annie eats %d apples in %.2f minutes, %d oranges in %.2f minutes", 4,5.2,7,7.3))
## [1] "Annie eats 4 apples in 5.20 minutes, 7 oranges in 7.30 minutes"
sprintf("%d-%d : %.2f", 1:20, 4:23, 5.4)
##  [1] "1-4 : 5.40"   "2-5 : 5.40"   "3-6 : 5.40"   "4-7 : 5.40"  
##  [5] "5-8 : 5.40"   "6-9 : 5.40"   "7-10 : 5.40"  "8-11 : 5.40" 
##  [9] "9-12 : 5.40"  "10-13 : 5.40" "11-14 : 5.40" "12-15 : 5.40"
## [13] "13-16 : 5.40" "14-17 : 5.40" "15-18 : 5.40" "16-19 : 5.40"
## [17] "17-20 : 5.40" "18-21 : 5.40" "19-22 : 5.40" "20-23 : 5.40"
.Internal(sprintf("%d-%d : %.2f", 1:20, 4:23, 5.4))
##  [1] "1-4 : 5.40"   "2-5 : 5.40"   "3-6 : 5.40"   "4-7 : 5.40"  
##  [5] "5-8 : 5.40"   "6-9 : 5.40"   "7-10 : 5.40"  "8-11 : 5.40" 
##  [9] "9-12 : 5.40"  "10-13 : 5.40" "11-14 : 5.40" "12-15 : 5.40"
## [13] "13-16 : 5.40" "14-17 : 5.40" "15-18 : 5.40" "16-19 : 5.40"
## [17] "17-20 : 5.40" "18-21 : 5.40" "19-22 : 5.40" "20-23 : 5.40"
## Unit: microseconds
##                                                                                                         expr
##             sprintf("Annie eats %d apples in %.2f minutes, %d oranges in %.2f minutes",      4, 5.2, 7, 7.3)
##  .Internal(sprintf("Annie eats %d apples in %.2f minutes, %d oranges in %.2f minutes",      4, 5.2, 7, 7.3))
##                                                                     sprintf("%d-%d : %.2f", 1:20, 4:23, 5.4)
##                                                          .Internal(sprintf("%d-%d : %.2f", 1:20, 4:23, 5.4))
##     min      lq     mean  median      uq    max neval
##   2.187  2.2690  2.45379  2.2985  2.3825  6.823   100
##   1.679  1.7275  1.90558  1.7510  1.7855 15.821   100
##  18.345 18.4695 19.04130 18.6315 18.9070 43.289   100
##  17.876 18.0065 18.39554 18.1335 18.2910 27.644   100