在ggplot的分面内更改因子顺序

3
我试图使用facet_grid()绘制多个图表,对于每个小部件,我希望在手动顺序下沿X轴绘制不同因子水平的子集。
基本上,我想在每个X轴上绘制前5个国家(手动定义),我可以使用grid.arrange()的替代解决方案(请参见示例),但我希望使用facet_grid()facet_wrap()来保持与我的其他图表相同的美学效果。
我可以找到一些按因子级别排序小部件的答案,并尝试使用order美学进行操作,但没有成功,所以我想知道是否有办法做到这一点,尽管我知道在ggplot中进行分面设计并不是为了修改坐标轴。我会感激任何关于此的建议。
以下是我想要的可重现示例(在X轴上手动定义顺序)。
library(reshape)
library(ggplot2)
library(gridExtra)

# Load data
mtcars_melt <- melt(mtcars)

# Subset data
set1 <- subset(mtcars_melt, variable == "mpg" | variable == "wt" | variable == "qsec")
set2 <- subset(mtcars_melt, variable == "gear" | variable == "cyl" | variable == "mpg")
set3 <- subset(mtcars_melt, variable == "drat" | variable == "vs" | variable == "mpg")

# Order factors
set1$variable <- factor(set1$variable, levels = c("mpg", "wt", "qsec"))
set2$variable <- factor(set2$variable, levels = c("mpg", "gear", "cyl"))
set3$variable <- factor(set3$variable, levels = c("vs", "mpg", "drat"))

# Make plots
plot1 <- ggplot(set1, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
plot2 <- ggplot(set2, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()
plot3 <- ggplot(set3, aes(x = variable, y = value)) + ylim(0, 35) + geom_boxplot()

grid.arrange(plot1, plot2, plot3, ncol = 3)

这是一个示例图表:

示例图表


关于IT技术的内容,需要更具体的指示。

1
我不会感到惊讶,如果这是不可能的。facet_grid/wrap 的重点是有可比较的分面。迄今为止,只有轴刻度是可调的,在一个轴上交换实际值可能在某些圈子被认为是不诚实的。 - Roman Luštrik
我认为主要的方法是创建一个新的因子,该因子是x变量和facet变量的组合,并在按照您喜欢的方式排序后将其用作x变量。请参见此处 - aosmith
@chenga 你所说的“与我的其他绘图具有相同的美学”是什么意思?我认为你可以在grid.arrange中实现。 - timat
1个回答

4
如何进行一个令人不爽的hack?
这将你的子集合并成一个新的数据框(dataframe)。然后添加了一列,将集合编号与变量连接起来,以使每个变量都是唯一的。问题在于,这会影响到你的x轴名称,因为它们是连接在一起的名称。为了解决这个问题,我采用了这个hack:R: Reorder facet_wrapped x-axis with free_x in ggplot2,删除了轴名称,并使用geom_text代替。 enter image description here
mtcars_melt <- melt(mtcars)

# Subset data
set1 <- subset(mtcars_melt, variable == "mpg" | variable == "wt" | variable == "qsec")
set2 <- subset(mtcars_melt, variable == "gear" | variable == "cyl" | variable == "mpg")
set3 <- subset(mtcars_melt, variable == "drat" | variable == "vs" | variable == "mpg")

# Order factors
set1$variable <- factor(set1$variable, levels = c("mpg", "wt", "qsec"))
set2$variable <- factor(set2$variable, levels = c("mpg", "gear", "cyl"))
set3$variable <- factor(set3$variable, levels = c("vs", "mpg", "drat"))


names(set1)[2]<-"set1"
names(set2)[2]<-"set2"
names(set3)[2]<-"set3"


mset1<-melt(set1)
mset2<-melt(set2)
mset3<-melt(set3)

library(data.table)
new<-as.data.frame(rbindlist(list(mset1,mset2,mset3)))
names(new)[2]<-'setno'

new$lvl <- with(new,paste(variable,setno,sep="."))
new$lvl<-as.factor(new$lvl)
new$lvl<-factor(new$lvl,levels=c("mpg.set1","wt.set1","qsec.set1","mpg.set2","gear.set2","cyl.set2", "vs.set3" , "mpg.set3","drat.set3" ))


plot1 <- ggplot(new, aes(x = lvl, y = value)) + ylim(0, 35) + geom_boxplot()+
  facet_wrap(~setno,scales="free_x")+
  ylim(-2,NA)+
  geom_text(aes(y=-1,label=variable),angle=45,size=5,hjust=1)+
  theme(axis.text.x = element_blank(),
        axis.title.x = element_blank(),
        axis.line.x = element_blank(),
        axis.ticks.x = element_blank())+
  geom_hline(aes(yintercept=0))

@chenga,你觉得这个有用吗? - J.Con
1
嗨J.Con,是的,这非常有用,而且是一种我不知道的非常有趣的方法。然而,我花了一些时间尝试使图表按照我的意愿工作,但我的示例比这些示例更复杂(我需要对数y轴等),因此最终我仍然选择了'grid.arrange()'。感谢您提供这个有趣的例子。@timat - 'facet_wrap()'图表有一个特定的外观(我可以在某种程度上模仿它们),因此我希望我所有的图表都具有统一的外观...这就是我所说的"同样的美学"的意思。 - chenga

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