Fizz, Buzz, or FizzBuzz?
Just to add to @flodel's comments, here is a properly vectorized version. One can see this is quite a bit faster, outperforming the parallel option (on 7 cores) by a factor 5. This problem is a quite nice demonstration of why is is worth your time to think about vectorized code:

flodel_fizzbuzz &lt;- function(range = 100, fizz = 3, buzz = 5) {
  s &lt;- 1:range
  is.fizz &lt;- s %% fizz == 0
  is.buzz &lt;- s %% buzz == 0

  s[is.fizz] &lt;- 'Fizz'
  s[is.buzz] &lt;- 'Buzz'
  s[is.fizz &amp; is.buzz] &lt;- 'FizzBuzz'
  return(s)
}


Running the benchmarks from @Gerard's answer (note that vectorizedFizzBuzz isn't truly vectorized):

Unit: milliseconds
                      expr       min        lq      mean    median        uq       max neval  cld
      applyFizzBuzz(range) 296.52224 303.19205 315.76901 309.18860 320.01676 384.18786    20   c 
 vectorizedFizzBuzz(range) 341.41121 356.82580 374.53857 362.45300 372.81459 461.65169    20    d
   parallelFizzBuzz(range) 117.40058 128.91812 158.66095 153.87976 170.76776 288.99613    20  b  
  papasmurfFizzBuzz(range) 292.22177 301.48002 316.31151 307.31605 319.05426 393.53235    20   c 
    flodel_fizzbuzz(range)  27.98101  29.15677  29.93554  29.93097  30.84586  32.09304    20 a   



I do think functions are a nice way to perform these tasks.
The easiest way to create a range of subsequent integers is with :.




This tidyverse version does about equally well (with ~40 ms):

tidy_fizbuzz &lt;- function(range = 100, fizz = 3, buzz = 5) {
  x &lt;- 1:range
  dplyr::case_when(
    x %% (fizz * buzz) == 0 ~ "Fizz Buzz",
    x %% fizz == 0 ~ "Fizz",
    x %% buzz == 0 ~ "Buzz",
    TRUE ~ as.character(x)
  )
}