ℕʘʘḆḽḘ
ℕʘʘḆḽḘ

Reputation: 19395

cannot use ggsave after marrangeGrob

I am using the following setup to create a list of charts.

This works pretty well:

library(grid)
library(gridExtra)
library(ggplot2)

mycols <- c('year','displ')

mylist <- list()
for(item in mycols){

  p <- ggplot(mpg, aes_string(x = 'hwy', y = item)) +  
    geom_point()
  mylist[[(length(mylist) +1)]] <- p
}

ml = marrangeGrob(grob = mylist, nrow=2, ncol=1)
ggsave("P://multipage.pdf", ml, width =10, height = 5)

However, in the loop, replacing:

Error in $<-.data.frame(*tmp*, "wrapvp", value = list(x = 0.5, y = 0.5, : replacement has 17 rows, data has 234

What is the problem here? Individually, all the charts in the list look fine.

Thanks!

Upvotes: 0

Views: 1034

Answers (1)

MrFlick
MrFlick

Reputation: 206486

This really has nothing to do with marrangeGrob and has to do with how you are building your list. Compare the structure of the output of these methods

out1 <- list()
out1[[length(out1)+1]]<-list(a=1, b=2)
out1[[length(out1)+1]]<-list(a=2, b=2)
str(out1)
# List of 2
#  $ :List of 2
#   ..$ a: num 1
#   ..$ b: num 2
#  $ :List of 2
#   ..$ a: num 2
#   ..$ b: num 2

out2 <- list()
out2 <- append(out2, list(a=1, b=2))
out2 <- append(out2, list(a=2, b=2))
str(out2)
# List of 4
#  $ a: num 1
#  $ b: num 2
#  $ a: num 2
#  $ b: num 2

Notice that they produce different structures. The append() adds the elements to the "root" list rather than nesting the list in the list. You can explicitly do that yourself with and extra list()

out3 <- list()
out3 <- append(out3, list(list(a=1, b=2)))
out3 <- append(out3, list(list(a=2, b=2)))
str(out3)
# List of 2
#  $ :List of 2
#   ..$ a: num 1
#   ..$ b: num 2
#  $ :List of 2
#   ..$ a: num 2
#   ..$ b: num 2

but messing with loops in R like this is rarely necessary. Better to use a built in iterator like lapply() or Map(). For example

mylist <- lapply(mycols, function(item) {
  ggplot(mpg, aes_string(x = 'hwy', y = item)) + 
    geom_point()
})

Upvotes: 2

Related Questions