I am a little bit puzzled when using lists of lists. If I try the following code, I get an error and I don't understand why:
library(tibble)
data <- list()
data[1][[1]] <- tibble(year = rep(2010,4)) # works
data[1][[2]] <- tibble(year = rep(2011,4)) # gives me an error
# Warning message:
# In data[1][[2]] <- tibble(year = rep(2011, 4)) :
# number of items to replace is not a multiple of replacement length
Any help on this, would be appreciated.
CodePudding user response:
Try this:
data <- list()
data[[1]] = list()
data[[1]][[1]] <- tibble(year = rep(2010,4))
data[[1]][[2]] <- tibble(year = rep(2011,4))
output:
[[1]]
[[1]][[1]]
# A tibble: 4 × 1
year
<dbl>
1 2010
2 2010
3 2010
4 2010
[[1]][[2]]
# A tibble: 4 × 1
year
<dbl>
1 2011
2 2011
3 2011
4 2011
CodePudding user response:
If you want a list of tibbles you index like this.
data <- list()
data[1][[1]] <- tibble(year = rep(2010,4))
data[2][[1]] <- tibble(year = rep(2011,4))
str(data)
# List of 2
# $ : tibble [4 x 1] (S3: tbl_df/tbl/data.frame)
# ..$ year: num [1:4] 2010 2010 2010 2010
# $ : tibble [4 x 1] (S3: tbl_df/tbl/data.frame)
# ..$ year: num [1:4] 2011 2011 2011 2011
CodePudding user response:
The error happens because data[1][[2]] <- tibble(year = rep(2011, 4))
attempts to add a new column year
to the tibble it obtained by running data[1]
. It is generally advisable to use double brackets when working with lists.
To illustrate why, see the output of the following code:
l <- list()
l[1] <- tibble(year = rep(2010,4))
l
[[1]]
[1] 2010 2010 2010 2010
# subsetting with [1] can be surprising
l[1][1][1][1][1][1][1]
[[1]]
[1] 2010 2010 2010 2010
a tidyverse
-like way to construct such nested list, avoiding repetition in code, would be
#using tidyverses' purrr package
data <- list(purrr::map(2010:2011, ~ tibble(year = rep(.x, 4))))
An alternative, which one should be wary off, see the second circle of R Inferno on growing objects, is to properly initialize a list, and then populate it.
# initialize, then fill
data <- list(rep(list(NULL), 2))
data[[1]][[1]] <- f(2010)
data[[1]][[2]] <- f(2011)