Overview
昨天写了个R语言脚本,主要是借助ROCR
包画ROC
曲线,只是最后画图时,没用ROCR
提供的plot
函数画ROC
曲线,而是用ROCR
处理了数据后,提取了画图的数据,用ggplot2
包画了ROC
曲线。因为ggplot2
可以提供强大的自定义绘图功能,没想到也正是这个自定义样式函数,在移植的时候出现了一些兼容性问题。
1. 问题描述
我使用的ggplot2
样式函数,是一个我已经用了一年多的样式,专门写在了一个名字叫style.R
的R文件中,内容如下:
library(grid)
theme_custom <- function (base_size = 10, base_family = "serif") {
theme_grey(base_size = base_size, base_family = base_family) %+replace%
theme(
line = element_line(colour = "black", size = 1, linetype = 1, lineend = "butt"),
rect = element_rect(fill = "white", colour = "black", size = 1, linetype = 1),
text = element_text(family = base_family, face = "plain", colour = "black", size = base_size, hjust = 0.5, vjust = 0.5, angle = 0, lineheight = 0.9),
axis.text = element_text(size = rel(0.8), colour = "grey50"),
strip.text = element_text(size = rel(0.8)),
## used to delete the text up the picture
#strip.text = element_blank(),
axis.line = element_blank(),
axis.text.x = element_text(family = base_family, size = base_size * 1.2, lineheight = 0.8, vjust = 1.2),
axis.text.y = element_text(family = base_family, size = base_size * 1.2, lineheight = 0.8, hjust = 1.2),
axis.ticks = element_line(colour = "black", size=0.2),
axis.title.x = element_text(family = base_family, size = base_size*1.5, vjust = 0.5),
axis.title.y = element_text(family = base_family, size = base_size*1.5, angle = 90, vjust = 0.5),
axis.ticks.length = unit(0.15, "cm"),
axis.ticks.margin = unit(0.1, "cm"),
legend.background = element_rect (fill="white",colour="grey50", size=0.1, linetype=1),
legend.margin = unit(0.5, "cm"),
legend.key = element_rect(fill = "grey95", colour = "white"),
legend.key.size = unit(1.2, "lines"),
legend.key.height = NULL,
legend.key.width = NULL,
legend.text = element_text(family = base_family, size = base_size * 1.2),
legend.text.align = NULL,
##legend.title = element_text(family = base_family, size = base_size * 3, face = "bold", hjust = 1),
legend.title =element_blank(),
legend.title.align = NULL,
legend.position = c(0.7,0.15),
legend.direction = NULL,
legend.justification = "center",
legend.box = "horizontal",
panel.background = element_rect(fill = "white", colour = NA),
panel.border = element_rect(fill = NA, colour = "grey50"),
panel.grid.major = element_line(colour = "grey30", size = 0.5, linetype="dotted"),
panel.grid.minor = element_blank(),
#panel.grid.minor = element_line(colour = "grey30", size = 0.5, linetype="dotted"),
## panel.margin = unit(c(0.1, 0.1, 0.1, 0.1), "lines"),
strip.background = element_rect(fill = NA, colour = NA),
strip.text.x = element_text(family = base_family, size = base_size * 0.8),
strip.text.y = element_text(family = base_family, size = base_size * 0.8, angle = -90),
plot.background = element_rect(colour = NA, fill = "white"),
plot.title = element_text(family = base_family, size = base_size),
##plot.title = element_blank(),
plot.margin = unit(c(0.5, 1, 0.5, 0.5), "lines") #top,right,bottom,left
)
}
这个样式我在Mac
和Ubuntu 12.04
上都使用过,都可以正常使用,但是这两天在windows
和Ubuntu 15.04
上使用时都出了问题,报错如下:
警告信息:
`axis.ticks.margin` is deprecated. Please set `margin` property of `axis.text` instead
错误于FUN("text"[[1L]], ...) :
Theme element 'text' has NULL property: margin, debug
Calls: print ... element_render -> calc_element -> lapply -> FUN -> lapply -> FUN
停止执行
这其实是两个问题,一个警告,外加一个错误。
第一个警告信息很好理解,我把代码中的
axis.ticks.margin = unit(0.1, "cm"),
直接注释掉就没有了。但是在windows
和Ubuntu 15.04
上使用时,依然报错:
错误于FUN("text"[[1L]], ...) :
Theme element 'text' has NULL property: margin, debug
Calls: print ... element_render -> calc_element -> lapply -> FUN -> lapply -> FUN
停止执行
2. 错误复现
首先想到的就是:为什么在Mac
和Ubuntu 12.04
却没有报错,查了一些资料,终于在ggthemes的github issues 上面找到了原因,原因在于ggplot2
总是在不停地更新,而更新之后,对于旧版本的兼容性不是很好,我的Mac
和Ubuntu 12.04
使用的是旧版本,因此还可以正常使用,但是使用新版本的电脑就不能很好的兼容这段代码。因此我把mac
下的ggplot2
更新一下。在这里我并没有更新ggplot2
,而是更新了ggthemes
。
2.1 ggthemes
ggthemes包:丰富ggplot2的表现力 这个链接的名字已经解释了ggthemes
:
ggplot2包的最新0.93版本允许自定义主题,这样ggplot的表现力可以通过各种不同的主题获得提升。
ggthemes包就是ggplot2的主题扩展包,提供了供ggplot2使用的新主题,尺度,几何对象和一些新函数。
其实这一两节是我后面加上的,原因是我google的时候正好在ggthemes
的github issues
中找到了错误和复现的解决方法。 然后又理了一下思路,发现其实我想浮现这个问题,应该更新ggplot2
包就可以了,单纯更新ggthemes
应该会顺带更新它的依赖项,所以ggplot2
也顺带更新了。
这里也只是一个逻辑上的分析,标记一下,以后再仔细确认。
2.2 安装devtools
包
在R交互命令行下,运行下面的命令安装devtools
包:
install.packages("devtools")
2.3 从github
上更新ggthemes
安装devtools
包之后,就可以使用devtools
包直接从github
上更新最新的ggthemes
了,而不是从CRAN
上更新。 命令如下:
devtools::install_github("jrnold/ggthemes")
安装之后,重新运行ROC
画图代码,谢天谢地,也报了同样的错误。
3. 解决方法
很明显,这个是由于ggplot2
版本更新引起的一个兼容问题,在 github ggthemes issue=57可以找到答案:
It does look like the documentation for ggplot2 may not have been updated to account for changes made with ggplot2 2.0.0. ggplot2 version 2.0.0 added the elements
margin
anddebug
toelement_text
, so you need to change the text element of the theme...
新版本的ggplot2
中,text = element_text()
中,多了两个参数margin
和debug
,我们上面style.R
中,并没有使用这两个参数,所以才会报错,把style.R
中:
text = element_text(family = base_family, face = "plain", colour = "black", size = base_size, hjust = 0.5, vjust = 0.5, angle = 0, lineheight = 0.9),
修改为
text = element_text(family = base_family, face = "plain", colour = "black", size = base_size, hjust = 0.5, vjust = 0.5, angle = 0, lineheight = 0.9,margin = margin(), debug = FALSE),
重新运行画图的R代码,就可以正常绘图了。