title: How to process all text elements of ggplot through a function before output?
body: <p>I'm creating a set of functions for enciphering data plots as a hook for data literacy lessons.</p>
  
  <p>For example, this function performs an alphabetic shift of +/- X for any string input</p>
  
  <pre><code>enciphR&lt;-function(x,alg,key=F){
    x.vec&lt;-tolower(unlist(strsplit(x,fixed=T,split="")))#all lower case as vector
  
       #define new alphabet
        alphabet&lt;-1:26+alg
        alphabet.shifted.idx&lt;-sapply(alphabet,function(x) {if(x&gt;26){x-26}else{ if(x&lt;1){x+26}else{x}}})
        alphabet.shifted&lt;-letters[alphabet.shifted.idx]
  
        keyMat=cbind(IN=letters,OUT=alphabet.shifted)
  
      #encipher
        x1.1&lt;-as.vector(sapply(x.vec,function(s) {
           if(!s%in%letters){s}else{#If nonletter, leave it alone, else...
           keyMat[match(s,keyMat[,"IN"]),"OUT"]
           }},USE.NAMES = F))
  
        x2&lt;-paste0(x1.1,collapse="")
    if(key){
      out&lt;-list(IN=x,OUT=x2,KEY=keyMat)}
        else{
        out&lt;-x2
        }
        return(out)
  }
  </code></pre>
  
  <p>enciphR(letters,+1) yields "bcdefghijklmnopqrstuvwxyza"</p>
  
  <p>I want to feed a ggplot object into another function ggEnciphR(), which uses the enciphR() helper to encode all text elements of that object, according to the supplied cipher algorithm.</p>
  
  <p>So, start with a figure:</p>
  
  <pre><code>data("AirPassengers")
  require(ggplot2);require(reshape2)
  df &lt;- data.frame(Passengers=as.numeric(AirPassengers), year = as.factor(trunc(time(AirPassengers))), mnth = month.abb[cycle(AirPassengers)])
  
  (gg&lt;-qplot(mnth,Passengers,aes(col=year),data=df)+geom_line(aes(group=year,col=year)))
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/jI3rz.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jI3rz.png" alt="ggplot with unmodified text"></a></p>
  
  <p>now I define the ggCiphR function:</p>
  
  <pre><code>ggCiphR&lt;-function(ggGraph,alg){
    g&lt;-ggGraph
    pass2enciphR=function(x){enciphR(x,alg=alg)}
    #process all labels
    g$labels&lt;-lapply(g$labels,pass2enciphR)
  
    #process custom legend if present (sometimes works, depending on ggplot object)
    try(if(length(g$scales$scales)&gt;0){
      for(i in 1:length(g$scales$scales)){
        g$scales$scales[[i]]$name=enciphR(g$scales$scales[[i]],alg=alg)
      }
    })
    g
  }
  
  ggCiphR(gg,+1)
  </code></pre>
  
  <p>Yields:</p>
  
  <p><a href="https://i.stack.imgur.com/mCOs7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/mCOs7.png" alt="(Mostly) enciphered ggplot figure"></a></p>
  
  <p>This is getting there. Axis labels and legend title have been enciphered, but not tick values. Also, if my factor was Airline, instead of Year, I'd like that to be sent through enciphR, as well.</p>
  
  <p>I've searched high and wide and cannot for the life of me figure out how to modify x- and y-axis values and factor levels from the gg object. I don't want to have to recast the dataframe and regenerate the ggplot... ideally I can do this programmatically using the gg object. And also, it would (ideally) be flexible enough to work with different classes of data in X &amp; Y. Thoughts?</p>