How to plot filtered data with loop in R and combine them with facet_grid?

110 Views Asked by At

I am new in R, so my question could seem very trivial for someone, but I need a solution. I have a data frame:

`structure(list(Time = c(0, 0, 0), Node = 1:3, Depth = c(0, -10, 
-20), Head = c(-1000, -1000, -1000), Moisture = c(0.166, 0.166, 
0.166), HeadF = c(-1000, -1000, -1000), MoistureF = c(0.004983, 
0.004983, 0.004983), Flux = c(-0.00133, -0.00133, -0.00133), 
    FluxF = c(-0.00122, -0.00122, -0.00122), Sink = c(0, 0, 0
    ), Transf = c(0, 0, 0), TranS = c(0, 0, 0), Temp = c(20, 
    20, 20), ConcF = c(0, 0, 0), ConcM = c(0, 0, 0)), row.names = c(NA, 
3L), class = "data.frame")`.

I am able to plot a single TranS vs Time Single plot, where color = Transf (using scale_color_viridis). I want to create plots with a filtered data for( depth = -20, depth = -40 , -60, -80 and -100) Note: that title also have to be changed according to a depth value. These plots then I want to put next to each other using facet_grid.

I have tried in a such way:

plot_d20 <-plot_node %>% filter(plot_node$Depth == -20)
plot_d40 <-plot_node %>% filter(plot_node$Depth == -40)
plot_d60 <-plot_node %>% filter(plot_node$Depth == -60)
plot_d80 <-plot_node %>% filter(plot_node$Depth == -80)
plot_d100 <-plot_node %>% filter(plot_node$Depth == -100)

depth_plot <- c(plot_d20,plot_d40,plot_d60,plot_d80,plot_d100)

for (p in depth_plot){
ggpS<-ggplot(p, aes(Time, TranS, color=Transf) ) + 
  geom_point(alpha = 1)+
  scale_color_viridis(option = "D")+
  scale_x_continuous(limits = c(0,1400), breaks = seq(0,1400,200))+
  ggtitle('Solute Mass Transfer for depth = 20mm')
ggpS
}

But it doesn't work. R says: data must be a data frame, or another object coercible by fortify(), not a numeric vector. And I don't know how to make my title dynamic and combine it with facet_grid or on a single plot, but in this case, I will face difficulty to distinguish the lines and assigning the legend to the plot by color, because color already represents another variable. What is the possible way to accomplish that?

2

There are 2 best solutions below

1
M.Viking On

Edit: Understand the question differently.

facet_grid accepts a single data.frame, and uses one of that frames values to split a chart into multiple subplots. Your question describes combining multiples charts into a single chart, which is available as a function from the cowplot library. However, If you are interested in faceting the data, here is a way to filter and facet_wrap.

Example with Iris data:

library(tidyverse)
iris %>% 
  filter(Sepal.Length %in% c(6.4,5.7,6.7,5.1,6.3,5)) %>%  ### Your values here
  ggplot(aes(Petal.Length, Petal.Width, color=Species)) + 
  geom_point(alpha = 1) +
  scale_color_viridis_d()+ #(option = "D") + ### New function name
  #scale_x_continuous(limits = c(0,1400), breaks = seq(0,1400,200))+
  facet_wrap("Sepal.Length") +
  # facet_grid("Sepal.Length") + ### Alternative Layout
  ggtitle('Sepal Length Range')

enter image description here

0
zephryl On

To create a "grid" of plots with only one faceting variable, you'll actually want to use facet_wrap(). You can create your facet titles before plotting, and change the formatting of strip.text within theme() to make them look more "title-like."

library(dplyr)
library(ggplot2)

plot_node %>% 
  mutate(
    facet = paste0("Solute Mass Transfer for Depth = ", abs(Depth), "mm")
  ) %>% 
  ggplot(aes(Time, TranS, color=Transf)) + 
  geom_point(alpha = 1) +
  scale_color_viridis_c(option = "D") +
  scale_x_continuous(limits = c(0, 1400), breaks = seq(0, 1400, 200)) +
  facet_wrap(vars(facet), ncol = 2, scales = "free") +
  theme_minimal() + 
  theme(strip.text = element_text(size = 12, face = "bold"))