首页 > 解决方案 > 如何在输出前通过函数处理ggplot的所有文本元素?

问题描述

我正在创建一组用于加密数据图的函数,作为数据素养课程的钩子。

例如,此函数对任何字符串输入执行 +/- X 的字母移位

enciphR<-function(x,alg,key=F){
  x.vec<-tolower(unlist(strsplit(x,fixed=T,split="")))#all lower case as vector

     #define new alphabet
      alphabet<-1:26+alg
      alphabet.shifted.idx<-sapply(alphabet,function(x) {if(x>26){x-26}else{ if(x<1){x+26}else{x}}})
      alphabet.shifted<-letters[alphabet.shifted.idx]

      keyMat=cbind(IN=letters,OUT=alphabet.shifted)

    #encipher
      x1.1<-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<-paste0(x1.1,collapse="")
  if(key){
    out<-list(IN=x,OUT=x2,KEY=keyMat)}
      else{
      out<-x2
      }
      return(out)
}

enciphR(letters,+1) 产生“bcdefghijklmnopqrstuvwxyza”

我想将一个 ggplot 对象输入另一个函数 ggEnciphR(),该函数使用 enciphR() 助手根据提供的密码算法对该对象的所有文本元素进行编码。

所以,从一个图开始:

data("AirPassengers")
require(ggplot2);require(reshape2)
df <- data.frame(Passengers=as.numeric(AirPassengers), year = as.factor(trunc(time(AirPassengers))), mnth = month.abb[cycle(AirPassengers)])

(gg<-qplot(mnth,Passengers,aes(col=year),data=df)+geom_line(aes(group=year,col=year)))

带有未修改文本的ggplot

现在我定义 ggCiphR 函数:

ggCiphR<-function(ggGraph,alg){
  g<-ggGraph
  pass2enciphR=function(x){enciphR(x,alg=alg)}
  #process all labels
  g$labels<-lapply(g$labels,pass2enciphR)

  #process custom legend if present (sometimes works, depending on ggplot object)
  try(if(length(g$scales$scales)>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)

产量:

(大部分)加密的ggplot图

这是到达那里。轴标签和图例标题已加密,但刻度值未加密。另外,如果我的因素是航空公司,而不是年份,我也希望通过 enciphR 发送。

我进行了广泛搜索,但终生无法弄清楚如何从 gg 对象修改 x 轴和 y 轴值以及因子水平。我不想重铸数据框并重新生成 ggplot... 理想情况下,我可以使用 gg 对象以编程方式执行此操作。而且,它(理想情况下)会足够灵活,可以处理 X 和 Y 中不同类别的数据。想法?

标签: rggplot2

解决方案


推荐阅读