Y叔的enrichplot画图是如何将y轴text文本换行的

介绍

我们在使用Y叔的clusterProfiler包做过富集分析之后,然后使用enrichplot 绘制dotplotbarplot时,y轴的Description 部分可以换行了(从哪一版开始的我不记得)。

如下图:

那么是如何实现的呢?

其实可用两种方法实现这种换行。一种方法是Y叔的yulab.utils::str_wrap(string, width = getOption("width")) 函数。另一种方法是哈德利的stringr::str_wrap(string, width = 80, indent = 0, exdent = 0, whitespace_only = TRUE)

测试用enrichplot版本

packageVersion(pkg = "enrichplot")
## [1] ‘1.18.3’

函数介绍

yulab.utils::str_wrap

  • string 字符串
  • width 字符最大长度,Y叔在绘制富集结果时是又包装过的str_wrap(),数值写明width = 30 。我目前没找到修改Y叔该参数的方法
  • 该函数换行处仅为空格。
  • Y叔在封装函数时还写个了隐藏函数default_labeller ,使其也支持在下划线“_”处换行,其方法是将_ 替换为了空格“ ”。
  • 简单使用:
str <- "microtubule cytoskeleton organization involved in mitosis"
yulab.utils::str_wrap(str,30)
## [1] "microtubule cytoskeleton\norganization involved in\nmitosis"
  • 核心代码

很巧妙的写法,第一次见。

str_wrap <- function(string, width = getOption("width")) {
    result <- vapply(string,
           FUN = function(st) {
               words <- list()
               i <- 1
               while(nchar(st) > width) {
                   if (length(grep(" ", st)) == 0) break
                   y <- gregexpr(' ', st)[[1]]                  
                   n <- nchar(st)
                   y <- c(y,n)
                   idx <- which(y < width)
                   # When the length of first word > width
                   if (length(idx) == 0) idx <- 1
                   # Split the string into two pieces
                   # The length of first piece is small than width
                   words[[i]] <- substring(st, 1, y[idx[length(idx)]] - 1)
                   st <- substring(st, y[idx[length(idx)]] + 1, n)  
                   i <- i + 1
               }
               words[[i]] <- st
               paste0(unlist(words), collapse="\n")
           },
           FUN.VALUE = character(1)
    )
    names(result) <- NULL
    result
}

stringr::str_wrap

  • string 字符串
  • width = 80 字符串最大宽度
  • indent = 0,exdent = 0 非负整数,首行和后续行的缩进
  • whitespace_only = TRUE 为TURE时,仅支持空格换行;为FALSE时,支持任意非字母的字符处换行,(e.g. /, -).
  • 简单使用:
str <- "microtubule cytoskeleton organization involved in mitosis"
stringr::str_wrap(str,30)
## [1] "microtubule cytoskeleton\norganization involved in\nmitosis"

在绘图中的使用

示例数据

data(geneList, package = "DOSE")
de <- names(geneList)[1:100]
yy <- enrichGO(de, 'org.Hs.eg.db', 
               ont="ALL", 
               pvalueCutoff=0.01,
               readable = TRUE)

df <- as.data.frame(yy) %>% head(8)
df$Description %>% nchar()
## [1] 16 24 36 28 22 57 30 28

barplot(yy)          

换行的“描述”有2个。

yulab.utils::str_wrap方法

分为两种小写法。

  1. label_format默认为30,这里改为40,换行的“描述”成了1个。
enrichplot:::barplot.enrichResult(yy, label_format = 40)

  1. 显示使用yulab.utils::str_wrap的写法。

用ggplot2从头写。

df$Description_1 <- df$Description %>% yulab.utils::str_wrap(width = 30)
ggplot(data = df,aes(Count, Description_1))+
  geom_bar(stat = "identity")

stringr::str_wrap方法

这里只演示Y轴描述,不做美化处理。同样有两种方法实现。

比较直接容易接受的方法如下:

df$Description_2 <- df$Description %>% stringr::str_wrap(width = 30)
ggplot(data = df,aes(Count, Description_2))+
  geom_bar(stat = "identity")

可以看到,也是两个“描述”换行,换行位置也与上方一致。

优雅的写法

ggplot(data = df,aes(Count, Description))+
  geom_bar(stat = "identity")+
  scale_y_discrete(labels = function(x){stringr::str_wrap(x,width = 30)})

小结

新的问题:enrichplot 在本次测试版本中是没有enrichplot::barplot 函数的,但是我们依然可以使用graphics::barplot 进行绘图。这是如何实现的呢?结合enrichplot:::barplot.enrichResult 里的函数写法和函数注释中的##' @method barplot enrichResult,这是不是定义了一个S3类的method呢? 由于不是很理解面向对象的编程和实现方法,也没人可以求教,这个问题只能以后解决了。

小声感慨:我学R就是这么摸着石头过来的,不断的一点点触及未知,猜测未知,探索未知,但依然还是有了份生信的工作,初学者也加油吧。

最后,感谢Y叔和哈德利!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值