介绍
我们在使用Y叔的clusterProfiler
包做过富集分析之后,然后使用enrichplot
绘制dotplot与barplot时,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方法
分为两种小写法。
- label_format默认为30,这里改为40,换行的“描述”成了1个。
enrichplot:::barplot.enrichResult(yy, label_format = 40)
- 显示使用
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叔和哈德利!