R语言中使用formula调用plot()时ylab参数失效问题咨询
R语言中formula形式调用plot()时ylab参数失效的问题及解决方法
问题现象
当使用公式形式调用base R的plot()函数时,ylab参数会被忽略,但xlab、col、pch等参数可正常生效。示例如下:
x <- 1:5 y <- (1:5) * 2 plot(x, y) # 正常生效 plot(x, y, xlab="new x", ylab="new y") # 正常生效 plot(~ x + y) # 正常生效 plot(~ x + y, col="red", pch=3, xlab="new x", ylab="new y") # ylab失效,仍显示变量名"y"
直接调用base::plot()或graphics::plot()均会出现该问题。
原因分析
公式形式调用plot()时,实际执行的是未导出的graphics:::plot.formula函数(可通过getAnywhere(plot.formula)查看完整源码)。该函数在处理~ x + y这类二元变量公式时,会强制将ylab设为第二个变量的名称,覆盖用户传入的ylab参数;而xlab的处理逻辑则保留了用户传入的参数优先级,因此可以正常生效。
简便解决方法
方法1:手动修改y轴标签(最直接)
绘图完成后使用title()函数手动设置y轴标签,无需修改底层函数逻辑:
plot(~ x + y, col="red", pch=3, xlab="new x") title(ylab="new y")
方法2:重定义plot.formula函数(永久生效)
通过重新定义未导出的plot.formula函数,让它优先使用用户传入的xlab和ylab参数:
# 获取原plot.formula函数 plot.formula <- getAnywhere(plot.formula)$objs[[1]] # 修改函数逻辑,优先使用用户传入的标签参数 plot.formula <- function (formula, data = NULL, ..., subset, na.action = NULL) { mf <- match.call(expand.dots = FALSE) m <- match(c("formula", "data", "subset", "na.action"), names(mf), 0L) mf <- mf[c(1L, m)] mf$drop.unused.levels <- TRUE mf[[1L]] <- quote(stats::model.frame) mf <- eval(mf, parent.frame()) vars <- attr(attr(mf, "terms"), "variables")[-1L] if (length(vars) == 1L) { x <- mf[[1L]] plot(x, ..., xlab = deparse(vars[[1L]])) } else if (length(vars) == 2L) { x <- mf[[1L]] y <- mf[[2L]] args <- list(...) # 优先使用用户传入的标签,无则使用变量名 xlab <- if (!is.null(args$xlab)) args$xlab else deparse(vars[[1L]]) ylab <- if (!is.null(args$ylab)) args$ylab else deparse(vars[[2L]]) plot(x, y, ..., xlab = xlab, ylab = ylab) } else stop("formula should specify one or two variables") }
修改后再次调用公式形式的plot(),ylab参数即可正常生效。
方法3:切换至ggplot2绘图系统
如果业务允许切换绘图工具,ggplot2的公式接口不存在该问题,代码示例:
library(ggplot2) ggplot(data.frame(x, y), aes(x = x, y = y)) + geom_point(color = "red", pch = 3) + labs(x = "new x", y = "new y")
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

