从 ggplot 中提取一个方面

4

我有两个图表,分别显示不同类型的数据(疫苗和疾病),我想提取这些图表的部分以生成每个主题的图表,该图表具有疫苗和疾病,并且根据原始图表上的颜色进行着色

vac
  subject age  vaccine
1     E11 1.0 DTaP-IPV
2     E11 3.0 DTaP-IPV
3     E22 1.0 DTaP-IPV
4     E22 2.0     Rota
5     E22 3.0 DTaP-IPV
6     E22 3.3     Rota

ill
  subject age       illness
1     E11 0.5 ear infection
2     E11 2.0 ear infection
3     E22 0.8         fever
4     E22 1.2         fever
5     E22 3.0 ear infection

ggplot(vac,aes(x=age,y=subject,color=vaccine))+geom_point(size=5) +
  scale_color_brewer(palette="Set1",drop = FALSE)+facet_grid(subject~.)

OnlyVaccines

ggplot(ill,aes(x=age,y=subject,color=illness))+geom_point(size=5) +
  scale_color_brewer(palette="Set3",drop = FALSE)+facet_grid(subject~.)

OnlyFever

现在,我想要一个E11的图表,其中包含一行疫苗(用Set1颜色标识),和一行疾病(用Set3颜色标识),对于E22也是同样的。由于我有许多数据类型和大约40个主题,所以当然希望自动完成这个过程,而不是通过illustrator等手动完成。

我认为gtable是可行的方法,但不确定如何提取一个facet。

非常感谢!


你是否需要一个图例?如果是的话,那将会是另一个问题。 - MrFlick
我不需要图例。谢谢! - MoranY
@MoranY,你的问题得到了几个有用的答案。由于你是 Stack Overflow 的新手,我想向你指出以下帮助页面:当有人回答我的问题时我该怎么做? - Jaap
3个回答

1
下面的代码将vacill合并到一个数据框中(添加一个新变量type来区分疫苗和疾病),这将使我们能够在单个调用ggplot中绘制疾病和疫苗。代码有点笨重,但我希望它能让您更接近您想要的结果。
library(RColorBrewer)
library(gridExtra)

# Combine data frames vac and ill by adding a new column 
# called "type" and changing name of the third column to "condition"
vac$type = "Vaccine"
names(vac)[3] = "condition"

ill$type = "Illness"
names(ill)[3] = "condition"

dat = rbind(vac, ill)

# Convert condition to a factor to get the levels ordered properly
dat$condition = factor(dat$condition, 
                       levels=c(unique(dat$condition[dat$type=="Vaccine"]), 
                                unique(dat$condition[dat$type=="Illness"])))

dat
   subject age     condition    type
1      E11 0.5 ear infection Illness
2      E11 2.0 ear infection Illness
3      E22 3.0 ear infection Illness
4      E22 0.8         fever Illness
5      E22 1.2         fever Illness
6      E11 1.0      DTaP-IPV Vaccine
7      E11 3.0      DTaP-IPV Vaccine
8      E22 1.0      DTaP-IPV Vaccine
9      E22 3.0      DTaP-IPV Vaccine
10     E22 2.0          Rota Vaccine
11     E22 3.3          Rota Vaccine

现在我们为每个主题生成一个图形,将每个图形放入列表中,然后将所有图形保存在单个PDF文件中。 ggplot 代码的工作原理如下:
  • subject 进行分面,以便我们获得带有主题 ID 的条形。
  • type 进行分面,以便我们获得疾病和疫苗的单独图形。
  • 使用下面创建的调色板来获取所需的颜色

pal1 = c(brewer.pal(n=3, name="Set1")[1:2], brewer.pal(n=3, name="Set3")[1:2])

p = list() 
for (i in unique(dat$subject)) { 
  p[[i]] = ggplot(dat[dat$subject==i,], 
                  aes(x=age, y=condition, colour=condition)) +
    geom_point(size=5) + 
    scale_color_manual(values=pal1, drop=FALSE) + 
    facet_grid(type ~ subject, scale="free") + ylab("") + 
   guides(colour=FALSE) 
}

pdf("plots.pdf", 9,5)
do.call("grid.arrange", p)  
dev.off()

这是相关编程的内容,并包含HTML,下面是图表:enter image description here

1
在你的问题中创建的分面中,对于不在分面中的主题,你有空行。如果有大约40个主题,则会创建一个填充了一行和39个空行的分面,这可能不是你想要的。
另一种解决方案:
# merging the dataframes together
dat <- merge(vac, ill, by=c("subject","age"), all=TRUE, sort=TRUE)

# creating the plot
ggplot() +
  geom_point(data=dat[!is.na(dat$vaccine),], aes(x=age, y=subject, fill=vaccine), size=10, shape=22) +
  geom_point(data=dat[!is.na(dat$illness),], aes(x=age, y=subject, color=illness), size=7, shape=17) +
  scale_fill_brewer(palette="Set1") +
  scale_color_brewer(palette="Set2") +
  theme_bw()

这段话的意思是:给出如下结果:enter image description here

1

这里有一个快速解决方案,可能会帮助你朝着正确的方向前进。试一试。

require(reshape2)
require(plyr)
dat <- melt(join(vac, ill, type="full"), id.vars = c("subject", "age"), na.rm=TRUE)

ggplot(dat, aes(x=age,y=variable, color=value))+geom_point(size=5) +
  scale_color_brewer(palette="Set1",drop = FALSE)+facet_grid(subject~.)

谢谢Leandro,但这里的问题是我只能为所有点提供一个颜色方案。如果我单独生成图表,我可以为每个变量提供不同的颜色方案。谢谢! - MoranY
除了使用个人的色彩方案来形成一个“主要”的色彩方案,然后应用于整个图表之外,我不确定如何处理这个问题。但是为了做到这一点,您需要了解每种数据类型有多少因素。如果您需要帮助,我可以提供一个示例。 - Leo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接