如何通过因子对数据帧进行子集并重复每个子集的绘图?

时间:2013-10-02 20:55:25

标签: r split ggplot2

我是R的新手。请原谅我,如果这个问题有明显的答案,但我找不到解决办法。我有SAS的经验,可能只是以错误的方式考虑这个问题。

我有一个数据集,其中包含来自数百个受试者的重复测量,每个受试者在不同年龄段进行多次测量。每个主题由ID变量标识。我想用AGE为每个受试者(ID)绘制每个测量值(比如说身体重量)。

我用ggplot2做了这样的事情:

ggplot(data = dataset, aes(x = AGE, y = WEIGHT )) + geom_line() + facet_wrap(~ID)

这适用于少数主题,但不适用于整个数据集。

我也尝试过这样的事情:

ggplot(data=data, aes(x = AGE,y = BW, group = ID, colour = ID)) + geom_line()

这也适用于少数科目但数百科目无法阅读。

我尝试使用这样的代码进行子集化:

temp <- split(dataset,dataset$ID)

但我不确定如何使用生成的数据集。或者也许有一种方法可以简单地调整facet_wrap,以便创建单个图?

谢谢!

3 个答案:

答案 0 :(得分:19)

因为您想要拆分数据集并为每个级别的因子制作一个图表,所以我会使用plyr包中的一个split-apply-return工具来解决这个问题。

以下是使用mtcars数据集的玩具示例。我首先创建绘图并将其命名为p,然后使用dlply将数据集拆分为一个因子并返回每个级别的绘图。我正在利用%+%中的ggplot2替换图中的data.frame。

p = ggplot(data = mtcars, aes(x = wt, y = mpg)) + 
    geom_line()

require(plyr)
dlply(mtcars, .(cyl), function(x) p %+% x)

这将一个接一个地返回所有图。如果您命名结果列表对象,您也可以一次调用一个图。

plots = dlply(mtcars, .(cyl), function(x) p %+% x)
plots[1]

修改

我开始考虑根据因素在每个情节上加上一个标题,这看起来很有用。

dlply(mtcars, .(cyl), function(x) p %+% x + facet_wrap(~cyl))

修改2

以下是将这些内容保存在单个文档中的一种方法,每页一个图。这与名为plots的图表列表一起使用。它将它们全部保存到一个文档,每页一个图。我没有更改pdf中的任何默认值,但您当然可以探索可以进行的更改。

pdf()
plots
dev.off()

已更新以使用包dplyr代替plyr。这是在do中完成的,输出将有一个命名列,其中包含所有图表作为列表。

library(dplyr)
plots = mtcars %>%
    group_by(cyl) %>%
    do(plots = p %+% . + facet_wrap(~cyl))


Source: local data frame [3 x 2]
Groups: <by row>

  cyl           plots
1   4 <S3:gg, ggplot>
2   6 <S3:gg, ggplot>
3   8 <S3:gg, ggplot>

要查看R中的图,只需询问包含图的列。

plots$plots

并保存为pdf

pdf()
plots$plots
dev.off()

答案 1 :(得分:3)

几年前,我想做类似的事情 - 为约2500名参与者绘制个别轨迹,每次测量1-7次。我是这样做的,使用plyrggplot2

library(plyr)
library(ggplot2)

d_ply(dat, .var = "participant_id", .fun = function(x) {

    # Generate the desired plot
    ggplot(x, aes(x = phase, y = result)) +
        geom_point() +
        geom_line()

    # Save it to a file named after the participant
    # Putting it in a subdirectory is prudent
    ggsave(file.path("plots", paste0(x$participant_id, ".png")))

})

有点慢,但确实有效。如果你想在一个图中了解所有参与者的轨迹(比如你的第二个例子 - 也就是意大利面条图),你可以调整线条的透明度(尽管忘记着色它们):

ggplot(data = dat, aes(x = phase, y = result, group = participant_id)) + 
    geom_line(alpha = 0.3)

答案 2 :(得分:2)

lapply(temp, function(X) ggplot(X, ...))

X是您的子集数据

请注意,您可能必须明确print ggplot个对象(print(ggplot(X, ..))