Applying a function in a for loop gives a vector of results that are variable in length every time (for example the first iteration might give 4 numbers the 2nd might give 10 numbers etc) How can you apply a function in a for loop and save every iteration without using external to R packages?
CodePudding user response:
You can create a list (which can take elements of undefined lengths and class) beforehand, and update the list at each iteration with [[
.
To do so, you can use vector
with mode = "list"
and define the length of the list beforehand.
In this example, I use numeric
to create a numeric vector of 0s and of length i
, but you can use any function.
l <- vector(mode = "list", length = 10)
for (i in 1:10){
l[[i]] <- numeric(i)
}
output
# [[1]]
# [1] 0
#
# [[2]]
# [1] 0 0
#
# [[3]]
# [1] 0 0 0
#
# [[4]]
# [1] 0 0 0 0
#
# [[5]]
# [1] 0 0 0 0 0
#
# [[6]]
# [1] 0 0 0 0 0 0
#
# [[7]]
# [1] 0 0 0 0 0 0 0
#
# [[8]]
# [1] 0 0 0 0 0 0 0 0
#
# [[9]]
# [1] 0 0 0 0 0 0 0 0 0
#
# [[10]]
# [1] 0 0 0 0 0 0 0 0 0 0
CodePudding user response:
This is exactly what lapply
is designed for. Same effect as Mael's answer but in a single line.
lapply(seq(10), numeric)
#> [[1]]
#> [1] 0
#>
#> [[2]]
#> [1] 0 0
#>
#> [[3]]
#> [1] 0 0 0
#>
#> [[4]]
#> [1] 0 0 0 0
#>
#> [[5]]
#> [1] 0 0 0 0 0
#>
#> [[6]]
#> [1] 0 0 0 0 0 0
#>
#> [[7]]
#> [1] 0 0 0 0 0 0 0
#>
#> [[8]]
#> [1] 0 0 0 0 0 0 0 0
#>
#> [[9]]
#> [1] 0 0 0 0 0 0 0 0 0
#>
#> [[10]]
#> [1] 0 0 0 0 0 0 0 0 0 0
I know you were looking for only base packages, but purrr::map
also does this.
purrr::map(seq(10), numeric)
#> [[1]]
#> [1] 0
#>
#> [[2]]
#> [1] 0 0
#>
#> [[3]]
#> [1] 0 0 0
#>
#> [[4]]
#> [1] 0 0 0 0
#>
#> [[5]]
#> [1] 0 0 0 0 0
#>
#> [[6]]
#> [1] 0 0 0 0 0 0
#>
#> [[7]]
#> [1] 0 0 0 0 0 0 0
#>
#> [[8]]
#> [1] 0 0 0 0 0 0 0 0
#>
#> [[9]]
#> [1] 0 0 0 0 0 0 0 0 0
#>
#> [[10]]
#> [1] 0 0 0 0 0 0 0 0 0 0
There is Map
in base R, but I personally don't like it because the function comes first making it less "pipeable"
Map(numeric, seq(10))