Fill missing value based on ID
Your code does work but there are indeed better ways of doing this.

Some details could be improved in your current function:


You could replace which(!(1:max_id %in% x$id)) with setdiff(seq(min_id, max_id), x$id). It's more legible, and, more importantly, it does not rely on the fact that your IDs are the n first integers. (Consider for instance which(!(2:5 %in% c(2, 3, 5))): it does not return 4.)
start is assigned to 0 but is never modified, so you could get rid of this local variable.


But the main point is that growing a dataframe in a loop is generally not a good idea, as most of the time you can find better options. Here are two possible solutions:

1) With base R

y &lt;- data.frame(id = seq(min(x$id), max(x$id)))
x &lt;- merge(y, x, all.x = TRUE)
x$value[is.na(x$value)] &lt;- fill_value


2) With tidyr

library(tidyr)

complete(x, id = seq(min(id), max(id)), fill = list(value = fill_value))