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?
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()