Search code examples
rggplot2pastegeom-text

Subset or Grep for selectively pasting using Geom_Text in R


I am trying to add select text using geom_text for a series of ggplots I am generating using the lapply and split functions. Essentially I am creating one ggplot per Component.name.x with each of these plots containing 3 curves - one for each group.name.

So as a shortened example of what my data frame (working2.df) kind of looks like:

group.name    Component.name.x         TCAmount  Ratio   Slope   Intercept
1A-Alprazolam          Alprazolam         0.0      0.05    0.5       0.4
1A-Alprazolam          Alprazolam         1.5      0.07    0.5       0.4
1A-Alprazolam          Alprazolam         3.1      0.08    0.5       0.4
1A-Alprazolam          Alprazolam         6.25     0.10    0.5       0.4
2A-Alprazolam          Alprazolam         0.0      0.06    0.4       0.3
2A-Alprazolam          Alprazolam         1.5      0.08    0.4       0.3
2A-Alprazolam          Alprazolam         3.1      0.09    0.4       0.3
2A-Alprazolam          Alprazolam         6.25     0.10    0.4       0.3
1B-Alprazolam          Alprazolam         0.0      0.05    0.5       0.6
1B-Alprazolam          Alprazolam         1.5      0.08    0.5       0.6
1B-Alprazolam          Alprazolam         3.1      0.10    0.5       0.6
1B-Alprazolam          Alprazolam         6.25     0.11    0.5       0.6
1A-Codeine             Codeine            0.0      0.10    0.5       0.6
1A-Codeine             Codeine            1.5      0.30    0.5       0.6
1A-Codeine             Codeine            3.1      0.41    0.5       0.6
1A-Codeine             Codeine            6.25     0.62    0.5       0.6
2A-Codeine             Codeine            0.0      0.09    0.6       0.7
2A-Codeine             Codeine            1.5      0.29    0.6       0.7
2A-Codeine             Codeine            3.1      0.40    0.6       0.7
2A-Codeine             Codeine            6.25     0.62    0.6       0.7
1B-Codeine             Codeine            0.0      0.09    0.6       0.5
1B-Codeine             Codeine            1.5      0.28    0.6       0.5
1B-Codeine             Codeine            3.1      0.41    0.6       0.5
1B-Codeine             Codeine            6.25     0.61    0.6       0.5

Currently I am plotting the data using the following:

plotIntra<-function(working2.df){
    ggplot(working2.df,aes(x=TCAmount,y=Ratio, group=group.name, colour=group.name))+
        geom_smooth(method=lm, level=0.95, se=FALSE, aes(colour=group.name))+
        theme_bw()+
        ggtitle(working2.df$Component.name.x[1])+
        xlab("Amount (ng/mL)") +ylab("Response Ratio")+
        expand_limits(y=0)+
        geom_text(data=working2.df, aes(label=paste("y=", Slope[1], "x+", Intercept[1], sep="")))
}

lapply(split(working2.df, working2.df$Component.name.x), function(x) try(plotIntra(x)))

What I want is for R to grab each Slope and Intercept once per group.name and paste it on the graph with the corresponding curve. So far I have only managed to end up with the y=mx+b for ALL the curves on every plot (sigh) or to have the y=mx+b text pasted many many repeating times on the same plot.

What I have been trying to do (but don't know if it is possible) is to make R either think there is a subset of data which contains the Slope and Intercept only once and it matches by group.name, or to use grep or subset in some way to pull the data. Maybe something like this (but this doesn't work):

geom_text(data=working2.df, grep("1A", working2.df$group.name)), 
    aes(label=paste("y=", Slope[1], "x+", Intercept[1], sep=""))

Anyone think they can help with this and be a ggplot hero?!


Solution

  • You can collapse the values in your function and use a different data= parameter for the geom_text

    plotIntra<-function(working2.df){
        lbls <- aggregate(cbind(TCAmount,Ratio)~group.name+Slope+Intercept, working2.df, mean)
        ggplot(working2.df,aes(x=TCAmount,y=Ratio, group=group.name, colour=group.name))+
            geom_smooth(method=lm, level=0.95, se=FALSE, aes(colour=group.name))+
            theme_bw()+
            ggtitle(working2.df$Component.name.x[1])+
            xlab("Amount (ng/mL)") +ylab("Response Ratio")+
            expand_limits(y=0)+
            geom_text(data=lbls, aes(label=paste("y=", Slope[1], "x+", Intercept[1], sep="")))
    }
    
    lapply(split(working2.df, working2.df$Component.name.x), function(x) try(plotIntra(x)))