ggplot2减少重复性工作

简介

好的数据分析都应该具有灵活性这一优点。如果数据发生变化,或者出现一些很不利于基本假设的信息时,这时候我们应该能够快速、便捷地更改之前的图形。下面主要介绍三种减少重复性工作的方法。

迭代

ggplot2会将最后一次绘制或修改的图形存储下来,输入last_plot即可获取该图形。我们可以从一个最基本的图形开始,迭代式地逐步添加图层和调整标度,直到得到结果。下面的例子就是将一个区域放大,并添加新的图层来突出发现的信息:x值和y值相同的钻石很少。

qplot(x, y, data = diamonds, na.rm = TRUE)

id

last_plot() + xlim(3, 11) + ylim(3, 11)

id

last_plot() + xlim(4, 10) + ylim(4, 10)

id

last_plot() + xlim(4, 5) + ylim(4, 5)

id

last_plot() + xlim(4, 4.5) + ylim(4, 4.5)

id

last_plot() + geom_abline(colour = "red")

id

调整完后最好再写一个能生成最终图形的独立代码:

qplot(x, y, data = diamonds, na.rm = T) + geom_abline(colour = "red") + xlim(4, 4.5) + ylim(4, 4.5)

绘图模板

ggplot2图形的每一个组件都是一个对象:可以被创建、存储并独立应用于某个图形中。我们可以创建可重用的组件来自动执行某些常用的任务,从而不用多次重复输入冗长的函数。下面的例子创建了一个颜色标度并将其应用在两个图形中:

gradient_rb <- scale_colour_gradient(low = "red", high = "blue")
qplot(cty, hwy, data = mpg, colour = displ) + gradient_rb

id

qplot(bodywt, brainwt, data = msleep, colour = awake, log = "xy") + gradient_rb

id

同存储单个对象一样,也可以将ggplot2中的组件存储为list格式的列表。向某个图形中添加组件列表和将其中的组件按顺序逐个添加是一样的效果。下面的例子创建了两个连续标度,用来取消坐标轴标签和刻度。

xquiet <- scale_x_continuous("", breaks = NULL)
yquiet <- scale_y_continuous("", breaks = NULL)
quiet <- list(xquiet, yquiet)
qplot(mpg, wt, data = mtcars) + quiet

id

qplot(displ, cty, data = mpg) + quiet

id

类似地,创建一个改变图层默认设置的函数也很简单。下面创建一个在图形中添加线性模型的函数:

geom_lm <- function(formula = y ~ x) {
    geom_smooth(formula = formula, se = FALSE, method = "lm")
}
qplot(mpg, wt, data = mtcars) + geom_lm()

id

library(splines)
qplot(mpg, wt, data = mtcars) + geom_lm(y ~ ns(x, 3))

id

绘图函数

如果对某一种基本图形,我们反反复复地将其应用到不同的数据集或参数上,这时很有必要将其所有不同的选项封装成一个简单的函数。下面给个例子:

range01 <- function(x) {
     rng <- range(x, na.rm = TRUE)
     (x - rng[1] / diff(rng))
}

library(plyr)
library(reshape2)

pcp_data <- function(df) {
    numeric <- laply(df, is.numeric)
    df[numeric] <- colwise(range01)(df[numeric])
    df$.row <- rownames(df)
    dfm <- melt(df, id = c(".row", names(df)[!numeric]))
    class(dfm) <- c("pcp", class(dfm))
    dfm
}

pcp <- function(df, ...) {
    df <- pcp_data(df)
    ggplot(df, aes(variable, value)) + geom_line(aes(group = .row))
}

参考文献

[1][ggplot2:数据分析与图形艺术]