Find the minimum value that data could have had before it was rounded
You can firstly change by difference != 0 and then use na.locf to replace NAs by last available value recursively.

minimum_new &lt;- function(data) {
  answer &lt;- rep(NA, length(data))
  difference &lt;- c(0, diff(data, lag = 1, differences = 1)) / 2
  answer[1] &lt;- data[1]
  answer[difference != 0] &lt;- data[difference != 0] - difference[difference != 0]
  answer &lt;- zoo::na.locf(answer, na.rm = FALSE)
  answer
}


This version is faster for me by at least 2 times.

&gt; data &lt;- sample(10, 10000, replace = TRUE)
&gt; check &lt;- function(values) all(sapply(values[-1], function(x) identical(values[[1]], x)))
&gt; bench &lt;- microbenchmark::microbenchmark(loop = Minimum(data), vectorised = minimum_new(data), check=check)
Unit: microseconds
       expr      min       lq     mean   median       uq      max neval cld
       loop 1401.959 1415.552 1665.816 1457.274 1586.407 4620.835   100   b
 vectorised  742.325  758.183 1111.202  796.507 1383.268 2587.940   100  a 


With check it's also checks the equality of output.