Reputation: 274
I need to create plots sequentially from all files in a folder, add certain information from calculated values to the plot (e.g. Mean SOC, TNPP, ANPP, BNPP), and arrange them over as many pages as needed to array them in a 5 x 3 layout.
Please, find a sample folder with trial files here: https://www.dropbox.com/sh/evty00a0t9a062b/AAABG-rIq3Uhtlf-yOWo2fNGa?dl=0
Following different online sources and other threads, I have tried:
path <- "C:/Users/.../trialFiles"
dfs <- dir(path, "*.csv", full.names = FALSE, ignore.case = TRUE, all.files = TRUE)
plotModel <- function(df) {
dat <- read.csv(paste(path, df, sep = "/"), header = TRUE, sep = ",")
Time <- dat$time
SOC <- dat$somtc
AGBM <- dat$agcprd
BGBM <- dat$bgcjprd
time_frame <- Time >= oT & Time <= fT
sTime <- Time[time_frame]
sSOC <- SOC[sTime]
sAGBM <- AGBM[sTime]
sBGBM <- BGBM[sTime]
iM_AGBM <- mean(sAGBM)
iM_BGBM <- mean(sBGBM)
iMSOC <- mean(sSOC)
iTNPP <- sum(iM_AGBM, iM_BGBM)
plot(Time, SOC)
legend("bottomright", bty = "n", legend = paste(df, "\n\n",
"SOC =", format(iMSOC, digits = 6), "\n",
"TNPP =", format(iTNPP, digits = 6), "\n",
"ANPP =", format(iM_AGBM, digits = 5), "\n",
"BNPP =", format(iM_BGBM, digits = 5), sep = ""))
}
eq_plot <- lapply(dfs, plotModel)
nPlot <- length(eq_plot)
cols <- 3
layout <- matrix(seq(1, cols * ceiling(nPlot/cols)),
ncol = cols, nrow = ceiling(nPlot/cols))
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
for (i in 1:nPlot) {
matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
print(eq_plot[[i]], vp = viewport(layout.pos.row = matchidx$row,
layout.pos.col = matchidx$col))
}
It does not give me an error, but is not showing the graphs either, just displays the text specified in the legend.
I have also tried with ggplot as follows:
dfs <- dir(period, "*.csv", full.names = FALSE, ignore.case = TRUE, all.files = TRUE)
plotModel <- function(df) {
dat <- read.csv(paste(period, df, sep = "/"), header = TRUE, sep = ",")
Time <- dat$time
SOC <- dat$somtc
AGBM <- dat$agcprd
BGBM <- dat$bgcjprd
time_frame <- Time >= oT & Time <= fT
sTime <- Time[time_frame]
sSOC <- SOC[sTime]
sAGBM <- AGBM[sTime]
sBGBM <- BGBM[sTime]
iM_AGBM <- mean(sAGBM)
iM_BGBM <- mean(sBGBM)
iMSOC <- mean(sSOC)
iTNPP <- sum(iM_AGBM, iM_BGBM)
ggplot(dat, aes(x=Time, y=SOC)) +
geom_line() +
ggtitle(df, subtitle = paste("SOC =", format(iMSOC, digits = 6), "\n",
"TNPP =", format(iTNPP, digits = 6), "\n",
"ANPP =", format(iM_AGBM, digits = 5), "\n",
"BNPP =", format(iM_BGBM, digits = 5), sep = ""))
}
eq_plot <- lapply(dfs, plotModel)
multi.page <- ggarrange(eq_plot, nrow = 5, ncol = 3)
ggexport(multi.page, filename = "diag_plots")
But I get the following error message: ggplot2 doesn't know how to deal with data of class uneval
.
Please, forgive if cross posting. I have tried following the examples but there's something I am doing wrong.
Thanks
Upvotes: 2
Views: 716
Reputation: 3914
You need to save the plot within your function in an object and then return it. Here is the solution for the first 3 files in that directory. You will need to adjust the last 2 lines of this code to handle all your plots:
library(ggplot2)
library(ggpubr)
path <- "C:/Users/.../path/to/your/dir"
dfs <- dir(path, "*.csv", full.names = FALSE, ignore.case = TRUE, all.files = TRUE)
# define oT and fT
oT=100
fT=1000
plotModel <- function(df) {
dat <- read.csv(paste(path, df, sep = "/"), header = TRUE, sep = ",")
# This part can be optimized, see below the simplified version of the function
Time <- dat$time
SOC <- dat$somtc
AGBM <- dat$agcprd
BGBM <- dat$bgcjprd
time_frame <- Time >= oT & Time <= fT
sTime <- Time[time_frame]
sSOC <- SOC[sTime]
sAGBM <- AGBM[sTime]
sBGBM <- BGBM[sTime]
iM_AGBM <- mean(sAGBM)
iM_BGBM <- mean(sBGBM)
iMSOC <- mean(sSOC)
iTNPP <- sum(iM_AGBM, iM_BGBM)
# save graph in an object
g<- ggplot(dat, aes(x=Time, y=SOC)) +
geom_line() +
ggtitle(df,
subtitle = paste("SOC =", format(iMSOC, digits=6), "\n",
"TNPP =", format(iTNPP, digits=6), "\n",
"ANPP =", format(iM_AGBM, digits=5), "\n",
"BNPP =", format(iM_BGBM, digits=5), sep = ""))
return(g)
}
eq_plot <- lapply(dfs, plotModel)
ggarrange(eq_plot[[1]], eq_plot[[2]], eq_plot[[3]], nrow = 1, ncol = 3) %>%
ggexport(filename = "diag_plots.png")
dev.off()
The body of the function can be simplified for clarity and efficiency:
plotModel <- function(df) {
dat <- read.csv(paste(path, df, sep = "/"), header = TRUE, sep = ",")
var.means <- colMeans(dat[dat$time >= oT & dat$time <= fT, c("agcprd","bgcjprd","somtc")])
# save graph in an object
g<- ggplot(dat, aes(x=time, y=somtc)) +
geom_line() +
ggtitle(df,
subtitle = paste("SOC =", format(var.means["somtc"], digits=6), "\n",
"TNPP =", format(var.means["agcprd"] + var.means["bgcjprd"], digits=6), "\n",
"ANPP =", format(var.means["agcprd"], digits=5), "\n",
"BNPP =", format(var.means["bgcjprd"], digits=5), sep = ""))
return(g)
}
Upvotes: 1