Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning plot to a variable in a loop

Tags:

r

ggplot2

I am trying to create 2 line plots.

But I noticed that using a for loop will generate two plots with y=mev2 (instead of a plot based on y=mev1 and another one based on y=mev2).

The code below shows the observation here.

mev1 <- c(1,3,7)
mev2 <- c(9,8,2)
Period <- c(1960, 1970, 1980)
df <- data.frame(Period, mev1, mev2)

library(ggplot2)
# Method 1: Creating plot1 and plot2 without using "for" loop (hard-code)
plot1 <- ggplot(data = df, aes(x=Period, y=unlist(as.list(df[2])))) + geom_line()
plot2 <- ggplot(data = df, aes(x=Period, y=unlist(as.list(df[3])))) + geom_line()

# Method 2: Creating plot1 and plot2 using "for" loop
for (i in 1:2) {
   y_var <- unlist(as.list(df[i+1]))
   assign(paste("plot", i, sep = ""), ggplot(data = df, aes(x=Period, y=y_var)) + geom_line())
}

Seems like this is due to some ggplot()'s way of working that I am not aware of.

Question:

  • If I want to use Method 2, how should I modify the logic?
  • People said that using assign() is not an "R-style", so I wonder what's an alternate way to do this? Say, using list?
like image 902
daslie Avatar asked Dec 13 '19 10:12

daslie


People also ask

What is plotting R?

Plot. The plot() function is used to draw points (markers) in a diagram. The function takes parameters for specifying points in the diagram. Parameter 1 specifies points on the x-axis. Parameter 2 specifies points on the y-axis.


3 Answers

One possible answer with no tidyverse command added is :

library(ggplot2)

y_var <- colnames(df)
for (i in 1:2) {
  assign(paste("plot", i, sep = ""),
         ggplot(data = df, aes_string(x=y_var[1], y=y_var[1 + i])) +
           geom_line())
}

plot1
plot2

You may use aes_string. I hope it helps.

EDIT 1

If you want to stock your plot in a list, you can use this :

Initialize your list :

n <- 2 # number of plots
list_plot <- vector(mode = "list", length = n)
names(list_plot) <- paste("plot", 1:n)

Fill it :

for (i in 1:2) {
  list_plot[[i]] <- ggplot(data = df, aes_string(x=y_var[1], y=y_var[1 + i])) +
           geom_line()
}

Display :

list_plot[[1]]
list_plot[[2]]
like image 73
Rémi Coulaud Avatar answered Oct 20 '22 05:10

Rémi Coulaud


For lines in different "plots", you can simplify it with facet_wrap():

library(tidyverse)
df %>% 
gather(variable, value, -c(Period)) %>% # wide to long format
ggplot(aes(Period, value)) + geom_line() + facet_wrap(vars(variable))

enter image description here

You can also put it in a loop if necessary and store the results in a list:

# empty list
listed <- list()
# fill the list with the plots
for (i in c(2:3)){
     listed[[i-1]] <- df[,-i]  %>%
                      gather(variable, value, -c(Period)) %>% 
                      ggplot(aes(Period, value)) + geom_line()
                 }

# to get the plots
listed[[1]]
listed[[2]]
like image 2
s__ Avatar answered Oct 20 '22 05:10

s__


Why do you want 2 separate plots? ggplots way to do this would be to get data in long format and then plot.

library(tidyverse)

df %>%
  pivot_longer(cols = -Period) %>%
  ggplot() + aes(Period, value, color = name) + geom_line()

enter image description here

like image 1
Ronak Shah Avatar answered Oct 20 '22 07:10

Ronak Shah