Reputation: 35
I have got the following data:
Detector=c("A", "A", "A", "A","B", "B", "B", "B","C", "C", "C", "C")
hours=rep(c(0,4,24,48),3)
LoD=c(rep(25,4),rep(40,4),rep(34,4))
Ct=c(24,24.2,24.3,24,43,42,43,41,35,37,35,35.6)
Sample.Type=c(rep("T",2),rep("P",4),rep("T",5), rep("P",1))
d4.1=data.frame(Detector,hours, Ct, LoD, Sample.Type)
I want to plot Ct vs hours as a simple scatterplot, as a loop for each Detector, and show each detector's lod value as a horizontal line on the plot. I use the following code which works perfectly well:
for(i in unique(d4.1$Detector)) {
print(ggplot(d4.1[d4.1$Detector==i], aes(d4.1$hours[d4.1$Detector==i],
d4.1$Ct[d4.1$Detector==i], colour = d4.1$Sample.Type[d4.1$Detector==i]))+
geom_point()+
geom_hline(yintercept=mean(d4.1$LoD[d4.1$Detector==i]))+
ggtitle(paste("Figure", j,i, sep=" "))+
theme(plot.title = element_text(hjust =
0.5),plot.caption=element_text(hjust = 0))+
labs(x="Hours/Time Points", y="Ct",caption=paste("The solid black line
is the LoD(=",mean(d4.1$LoD[d4.1$Detector==i]),") for",i,sep=" "),
colour="Sample Types"))}
What I need help with is the ggplot's titles. Each of the plots generated is labeled with A,B and C but i'd like to add the following text to it:
Figure 1: A
Figure 2: B
Figure 3: C
I tried adding a "j" sequence of 1-3 and paste it in title (below) which didnt work. It gave me 9 plots (Figure 1 A,Figure 1 B, Figure 1 C, Figure 2 A...etc)
for(i in unique(d4.1$Detector)){for (j in seq(1:3)){print(ggplot(d4.1[which(d4.1$Detector==i),], aes(hours,Ct, colour = Sample.Type))+geom_point()+geom_hline(yintercept=mean(LoD))+ggtitle(paste("Figure",j,i,sep=" "))+theme(plot.title = element_text(hjust = 0.5),plot.caption=element_text(hjust = 0))+labs(x="Hours/Time Points", y="Ct",caption=paste("The solid black line is the LoD(=",mean(LoD),") for",i,sep=" "), colour="Sample Types"))}}
How do I add a sequence of numbers (1,2,3...) to ggplot titles in a loop? Thank you very much.
Upvotes: 0
Views: 314
Reputation: 256
Your code was not reproducible because the way you programmed your loop. You subset the dataframe first and then within your aes() ask for subsets that no longer exists.
Although I find Kristoffer's and Adam's answers more elegant than mine here is a crude version that uses your original loop. I use the fact that factor level A corresponds to the first level, by converting the factor to a numeric.
for(i in unique(d4.1$Detector)) {
print(ggplot(d4.1[d4.1$Detector==i,], aes(hours,
Ct, colour = Sample.Type))+
geom_point()+
geom_hline(yintercept=mean(d4.1$LoD[d4.1$Detector==i]))+
ggtitle(paste("Figure", as.numeric(d4.1$Detector[d4.1$Detector==i]), ":" , i, sep=" "))+
theme(plot.title = element_text(hjust =
0.5),plot.caption=element_text(hjust = 0))+
labs(x="Hours/Time Points", y="Ct",caption=paste("The solid black line
is the LoD(=",mean(d4.1$LoD[d4.1$Detector==i]),") for",i,sep=" "),
colour="Sample Types"))}
Upvotes: 0
Reputation: 1475
If you store unique Detector
in a variable (detectors
) and use seq_along
you will get indexes 1 to 3 (x
in the function). You can then create your three plots like this:
detectors <- unique(d4.1$Detector)
lapply(seq_along(detectors), function (x) {
selected_detector <- detectors[[x]]
df_plot <- d4.1[d4.1$Detector == selected_detector, ]
p <- ggplot(df_plot, aes(x = hours, y = Ct, colour = Sample.Type)) +
geom_point() + geom_hline(yintercept = mean(df_plot$LoD)) +
ggtitle(paste("Figure", x, selected_detector, sep = " ")) +
theme(plot.title = element_text(hjust = 0.5),
plot.caption = element_text(hjust = 0))+
labs(x = "Hours/Time Points", y = "Ct",
caption=paste("The solid black line is the LoD(=",
mean(df_plot$LoD),") for", selected_detector, sep=" "),
colour="Sample Types")
print(p)
})
Upvotes: 1
Reputation: 7163
Since your code is not reproducible, I'd decided to give an alternate example using the iris data.
(i) split iris into a list of 3 subset, based on Species. This is similar to d4.1[d4.1$Detector==i,]
in the code provided
df <- split(iris, iris$Species)
(ii) write a generic plot function that takes in different subset
plotFn <- function(df){
ggplot(df, aes(Sepal.Length, Petal.Length)) +
geom_point() +
geom_hline(yintercept = mean(df[,"Petal.Length"]))
}
(iii) get the list of ggplot object and then do a lapply to individually add in the Figure x: y
format.
p <- lapply(df, plotFn)
lapply(1:length(p), function(x){
p[[x]] +
ggtitle(paste0("Figure ", x, ": ", names(p)[x]))
})
This will provide three plots:
Upvotes: 0