rappendlapplyfacebook-prophet

How to deal with ´append´ like functions in lapply?


I have a function (more specifically prophet::add_regressor()) which appends values to an object. I recreated a similar function to make sure my point is clear:

add_to_a_list = function(object, item_to_add){
  
  object$a = append(object$a, item_to_add, after = T)
  
  return(object)
  
}

The tutorials using the particular function I stumbled on use the following ugly form:

stuff_to_add = c('raaa', 'ruuu', 'riii')
x = list(a = list(), b = list())

x = add_to_a_list(object = x, stuff_to_add[1])
x = add_to_a_list(object = x, stuff_to_add[2])
x = add_to_a_list(object = x, stuff_to_add[3])

str(x)

List of 2
 $ a:List of 3
  ..$ : chr "raaa"
  ..$ : chr "riii"
  ..$ : chr "ruuu"
 $ b: list()

While a for loop does the job:

stuff_to_add = c('raaa', 'ruuu', 'riii')
x = list(a = list(), b = list())

for(item in stuff_to_add){
  
  x = add_to_a_list(x, item)
  
}

str(x)


List of 2
 $ a:List of 3
  ..$ : chr "raaa"
  ..$ : chr "riii"
  ..$ : chr "ruuu"
 $ b: list()

Problem; I hate for loops in R and I always use lapply as replacement because I find it more intuitive and it is definitely faster and can be easily rewritten for parallel processing. However, I tried many variations of lapply and it does not give the expected result:

stuff_to_add = c('raaa', 'ruuu', 'riii')
x = list(a = list(), b = list())

x = lapply(stuff_to_add, function(item){
  
  add_to_a_list(x, item)
  
})

str(x)

List of 3
 $ :List of 2
  ..$ a:List of 1
  .. ..$ : chr "raaa"
  ..$ b: list()
 $ :List of 2
  ..$ a:List of 1
  .. ..$ : chr "ruuu"
  ..$ b: list()
 $ :List of 2
  ..$ a:List of 1
  .. ..$ : chr "riii"
  ..$ b: list()

How can I assign within lapply and force it to output the object in question instead of a list?


Solution

  • This looks like a job for Reduce:

    stuff_to_add <- c("raaa", "ruuu", "riii")
    x <- list(a = list(), b = list())
    
    add_to_a_list <- function(object, item_to_add) {
      object$a <- append(object$a, item_to_add, after = T)
    
      return(object)
    }
    
    Reduce(
      add_to_a_list,
      stuff_to_add,
      init = x
    )
    #> $a
    #> $a[[1]]
    #> [1] "raaa"
    #> 
    #> $a[[2]]
    #> [1] "riii"
    #> 
    #> $a[[3]]
    #> [1] "ruuu"
    #> 
    #> 
    #> $b
    #> list()