0

The dataframe looks like:

... year month country bincensored ...
    2017   4     JP        0
    2018   12    US        0
    2017   4     JP        1
    2019   6     LT        0
    2018   5     JP        1
    ...

The following code plots Japan (grouped by month) in 2017; I'd like to do this for all countries in 2017.

japan <- global %>%
         filter(country == "JP" & year == "2017") %>%
         group_by(month) %>%
         summarise(blocks = mean(bincensored))

japan$month <- as.numeric(japan$month)

k <- ggplot(data = japan, aes(x = month, y = blocks)) +
     geom_point() +
     geom_line()

k <- k + scale_x_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
                            labels = c("Jan", "Feb", "Mar", "Apr", "May",
                                       "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
zhlee
  • 63
  • 6
  • *So I guess it's something like a loop over countries nested in a loop over years.* -Sounds to me like a possible way to proceed. Or we could use `ggplot2::facet_grid` to split the plots by `year`... Not sure what the question is though ;) ? – dario Mar 08 '20 at 12:28
  • cann't you just add year and country to the group_by? – Annet Mar 08 '20 at 12:35
  • why don't you try `group_by(year, month, country)` without the `filter()` step above it. I guess it will give all summaries you want in one `dataframe`. Or are you after creating a separate dataframe for each country and year? That seems like an inefficient way of approaching this problem – M_Shimal Mar 08 '20 at 12:46
  • @dario so the code I provided in the question only plots Japan in 2017; I was wondering if there's a way I can do this to all countries in 2017. – zhlee Mar 08 '20 at 12:47
  • Could you provide a [minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5963610#5963610) in an edit to your question? – dario Mar 08 '20 at 12:49
  • After you create main summary `dataframe`as `df` in above comment, you can use filter to plot any summary data you want in ggplot. Like `df %>% filter(country == "US", year == "2018") %>% ggplot(...)` – M_Shimal Mar 08 '20 at 12:50
  • @M_Shimal Thank you! My code already successfully plotted the summary data in one country; the problem is I'd like to do this to all countries. There are ~50 countries and I don't think I should write the same codes with different countries filtered for ~50 times. Is there a faster way? Like through looping? – zhlee Mar 08 '20 at 13:00

2 Answers2

1

You could do this, but will still have to call separate plots to view them

Global <- data.frame(country = rep(c("US","JP","LT"), each = 72), 
                     year = "2017", 
                     month = rep(c(1:12), 18),
                     bincensored = sample(c(0,1), 216, replace = T))

# I am grouping by year here because you have many years in your dataset
df <- Global %>% 
  group_by(country, year, month) %>% 
  summarize(blocks = mean(bincensored))

# Just to show how similar this is to what you have been doing, you'll need to filter by year for your dataset for individual country plotting by year, as you've done
    df %>% filter(country == "JP") %>% 
      ggplot(aes(x = month, y = blocks)) +
      geom_point() +
      geom_line() + 
      scale_x_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
                         labels = c("Jan", "Feb", "Mar", "Apr", "May",
                                    "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))

pltlist <- list() # a list object to store you plots from loop

# You will need to filter df by year if you are plotting by year. Or alternatively can do that within a loop. 

for (i in unique(df$country)) {

  plt <- df %>% filter(country == i) %>% 
    ggplot(aes(x = month, y = blocks)) +
    geom_point() +
    geom_line() + 
    scale_x_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
                       labels = c("Jan", "Feb", "Mar", "Apr", "May",
                                  "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
  pltlist[[i]] <- plt
  # ggsave(filename = paste0("plt", i,".png"), plt)
}

pltlist[["US"]]
pltlist[["JP"]]

Note that I have only done this using a dummy dataset created for 2017. In your case, if you will want to filter by year. You could save the plots separately, by uncommenting the ggsave() component

Including year within the loop, to produce country by year plots

This is done from main summary df summarized by all years

   for (i in unique(df$country)) {
      for(y in unique(df$year)){
      plt <- df %>% filter(country == i, year == y) %>% 
        ggplot(aes(x = month, y = blocks)) +
        geom_point() +
        geom_line() + 
        scale_x_continuous(breaks = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
                           labels = c("Jan", "Feb", "Mar", "Apr", "May",
                                      "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"))
      pltlist[[paste0(i,y)]] <- plt
      # ggsave(filename = paste0("plt", i, y,".png", sep = "_"), plt)}
    }
M_Shimal
  • 413
  • 3
  • 12
  • Thank you!! But this gives "Error: Discrete value supplied to continuous scale." So I tried to as.numeric(unlist(pltlist[[paste0(i,j)]])), which didn't work. Does the nested loop you wrote work for you? – zhlee Mar 08 '20 at 23:59
  • 2
    Try `scale_x_discrete`. – Edward Mar 09 '20 at 01:07
  • It may be because your month column is `character` or `factor` column. In fact from you `japan$month <- as.numeric(japan$month)` code I assume it is read in not as a continuous numeric value first. In my example, month column is numeric. – M_Shimal Mar 09 '20 at 09:01
  • @Edward this works! Thank you! But when I tried to ggsave(), it gives "Error: Unknown graphics device ''" I tried all kinds of fixes but the error remains. – zhlee Mar 09 '20 at 14:33
0

Try this. Just replace airquality with your data and modify variables acordingly. The concept is the same.

airquality
str(airquality)

airquality %>%
  # filter whatever you want here
  filter(Month==6) %>%
  ggplot(aes(x = Day, y = Temp)) +
  geom_point() +
  geom_line()

# Facetting
airquality %>%
  mutate(Month = month.abb[Month]) %>%
  ggplot(aes(x = Day, y = Temp)) +
  geom_point() +
  geom_line() -> p

p + facet_wrap(~Month)
p + facet_grid(~Month)
p + facet_grid(Month~.)

# One month per plot
for(month in unique(airquality$Month)) {
  airquality %>%
    filter(Month == month) %>%
    mutate(Month = month.abb[Month]) %>%
    ggplot(aes(x = Day, y = Temp)) +
    geom_point() +
    geom_line() +
    ggtitle(paste0("Month: ", month.name[month]))
  ggsave(file=paste("E:/SO/myRplot_", month.abb[month], ".png"))
}
Edward
  • 10,360
  • 2
  • 11
  • 26