Search code examples
rjpegigraphlapply

Function for plotting and saving igraph objects skips list elements when using lapply


I have a list of network objects and I would like to go through the list, plot each network and save the plot to my working directory.

# creating list of networks
networks <- list()
networks[[1]] <- graph(c("A","B"))
networks[[2]] <- graph(c("C","D"))
networks[[3]] <- graph(c("E","F"))

Expected Output that I would like to save to the working directory:

# looking at plots
plot(networks[[1]])
plot(networks[[2]])
plot(networks[[3]])

As my list is rather long and in the original example I need to pass down some initial parameters, I would like to have a function that plots and saves each network and then lapply() it to the list. Here´s what I tried:

# generating and saving plots automatically
Plotter <- function(network){

        # Generate some random number so plots don´t get overwritten
        Rand <- runif(1,0,100000)

        # setting seed
        set.seed(123)

        # set up picture device
        jpeg(paste(Rand,"NetworkPlot.jpg",sep=""),
             width = 800,
             height = 800,
             units = "px",
             quality = 100)

        # plotting the network
        plot(network)

        # saving to wd
        dev.off()

}

# Applying function to list of networks
lapply(networks,Plotter)

What I would expect are three different plots in my working directory. However, if I go to the wd, I only see the first and the last plots.

At first I thought it might be an unlikely coincidence when the same Rand gets picked and the file is overwritten. But I tried several times and it happens every time.


Solution

  • Given the way that you generated the names, it is not so unlikely that the same numbers will be generated twice. In fact, it is guaranteed. Your code says:

    # Generate some random number so plots don´t get overwritten
    Rand <- runif(1,0,100000)
    
    # setting seed
    set.seed(123)
    

    The first time it is executed, it will generate one random number between 0 and 100000. Then you set the random seed to 123. The second time that you execute the function, it will generate a number starting from the seed 123. Then reset the seed to 123. Every subsequent time, it will generate a number from the random seed 123 and overwrite the all previous results except the first. So you get the first and the last. Just delete the line that sets the seed and you will get all different numbers and therefore different file names.

    If you want to test this, leave your code as is, but add the line

    write(paste0(Rand, "\n"), stderr())
    

    just after you generate Rand.