Convert data frame to list of lists by row
without any external packages:

feat3 &lt;- function(coords, height = 20, vjust = 75,  fill = "blue"){
  xx &lt;- apply(coords, 1, function(x) {
    list(type = "rect",
         x = as.numeric(x[1]), 
         y = vjust, 
         width = as.numeric(x[2] - x[1]),
         height = height,
         fill = fill)
    }
  )
  return(xx)
}

all.equal(feat3(coords), result)
# [1] TRUE


Benchmarks:

microbenchmark::microbenchmark(
  feat3(coords),
  feat2(coords), unit = "relative"
)
# Unit: relative
# expr      min       lq     mean   median       uq      max neval cld
# feat3(coords)   1.0000   1.0000   1.0000   1.0000   1.0000   1.0000   100  a 
# feat2(coords) 315.8261 297.2919 254.5025 258.7822 248.2652 286.9575   100   b