ggplot2:x轴上的多个变量多次

时间:2019-06-16 21:15:38

标签: r ggplot2

我有一个数据框,用于观察编号(3个观察值相同的id),身高,体重和前瞻性数据(例如):

id      obs     height  weight       fev
1         1        160     80         90
1         2        150     70         85
1         3        155     76         87
2         1        140     67         91
2         2        189     78         71
2         3        178     86         89

我需要使用ggplot2绘制此数据,以便在x轴上有3个变量,分别是高度,重量,fev;每个变量(颜色编码)的观察号显示为3条垂直线,其中每条线将中位数显示为实心圆,并在行的上下两端(第25个和第75个百分位数)作为上限(无最小值或最大值)需要)。到目前为止,我已经尝试了许多箱形图的变体,但是我什至没有接近。有什么建议可以解决或解决这个问题吗?

谢谢

2 个答案:

答案 0 :(得分:0)

在绘制图形之前,请尝试将数据放入长格式。我生成了更多数据,包括12个主题,每个主题都有3个观察结果。

id <- rep(1:12, each = 3)
obs <- rep(1:3, 12)
height <- seq(140,189, length.out =  36)
weight <- seq(67,86, length.out = 36)
fev <- seq(71,91, length.out = 36)

df <- as.data.frame(cbind(id,obs,height, weight, fev))


library(reshape2) #use to melt data from wide to long format

longdf <- melt(df,id.vars = c('id', 'obs')) 

由于定义了id.vars,因此无需在此处定义度量变量,其余的非id.vars自动默认为度量变量。如果数据集中有更多变量,则需要在同一行中定义度量变量,例如:measure.vars = c(“ height,” weight“,” fev“)

longdf <- melt(df,id.vars = c('id', 'obs'), measure.vars = c("height", "weight", "fev"))

道歉,没有赢得足够的选票,无法在我的回应中加入数字

ggplot(data = longdf, aes(x = variable, y = value, fill = factor(obs))) + 
geom_boxplot(notch = T, notchwidth = .25, width = .25, position = position_dodge(.5))

这不是不是生成您所描述的确切图形的方法-听起来像是geom_linerange或类似的东西? -这些几何需要绘制x,ymin和ymax。否则,常规的ole箱形图会标出您的第一和第三IQR和中位数。我调整了箱形图的参数以使其更窄,更窄,并使用position_dodge(.5)

阅读您的回复后,我编辑了原始答案

您可以尝试 facet_wrap -并观察ggplot中“填充”与“颜色”的交换。如果对象不能像盒图或分布图那样用颜色“填充”,那么就必须用颜色“着色”。在原始aes()

中使用颜色代替
ggplot(data = longdf, aes(x = variable, y = value, color = factor(obs))) + 
stat_summary(fun.data=median_hilow) + facet_wrap(.~obs)

这将为您提供观察1-身高,体重,肩并肩,观察2-身高....

如果那仍然不是您想要的,则可能更像是高度观测1,2,3;重量观察1,2,3 ...然后您需要修改融化以具有两个变量和两个值列。本质上是制作两个融化的数据帧,然后绑定。 Annnnd因为每个观察值都有三个变量,所以您需要rbind来确保两个数据框具有相同的行数:

 obsonly <- melt(df, id.vars = c('id'), measure.vars = 'obs')

 obsonly <- rbind(obsonly,obsonly,obsonly) #making rows equal 

 longvars <- melt(df[-2],id.vars = 'id') #dropping obs from melt

 longdf2 <- cbind(obsonly,longvars)

 longdf2 <- longdf2[-4] #dropping second id column


 colnames(longdf2)[c(2:5)] <- c('obs', 'obsnum', 'variable', 'value')

 ggplot(data = longdf2, aes(x = obsnum, y = value, 
         color = factor(variable))) + 
         stat_summary(fun.data=median_hilow) +
         facet_wrap(.~variable)

从这里开始,您可以使用x轴标记(标记为1.5的观察点可能没有用)以及行与行之间的间距

答案 1 :(得分:0)

好吧,相反,我在下面所做的是制作三个图形,然后与gridExtra拼凑在一起。在此处详细了解软件包:http://www.sthda.com/english/wiki/wiki.php?id_contents=7930

我从这个站点上获取了常见的图例代码,从我们现有的longdf2开始制作了以下代码。通过将图拼凑在一起,有关观察的信息就在图的标题之内

id <- rep(1:12, each = 3)
obs <- rep(1:3, 12)
height <- seq(140,189, length.out =  36)
weight <- seq(67,86, length.out = 36)
fev <- seq(71,91, length.out = 36)

df <- as.data.frame(cbind(id,obs,height, weight, fev))

obsonly <- melt(df, id.vars = c('id'), measure.vars = 'obs')

obsonly <- rbind(obsonly,obsonly,obsonly)

newvars <- melt(df[-2],id.vars = 'id')

longdf2 <- cbind(obsonly,newvars)

longdf2 <- longdf2[-4] #dropping second id column

colnames(longdf2)[c(2:5)] <- c('obs', 'obsnum', 'variable', 'value')

#Make graph 1 of observation 1

g1 <- longdf2 %>%
  dplyr::filter(obsnum == 1) %>%
  ggplot(aes(x = variable, y = value, color = variable)) + 
    stat_summary(fun.data=median_hilow) +
      labs(title = "Observation 1") +
       theme(plot.title = element_text(hjust = 0.5)) #has a legend

g2 <- longdf2 %>%
dplyr::filter(obsnum == 2) %>%
ggplot(aes(x = variable, y = value, color = variable)) + 
  stat_summary(fun.data=median_hilow) +
    labs(title = "Observation 2") +
     theme(plot.title = element_text(hjust = 0.5), legend.position = 
        'none')
    #specified as none to make common legend at end

g3 <- longdf2 %>%
   dplyr::filter(obsnum == 3) %>%
   ggplot(aes(x = variable, y = value, color = variable)) + 
     stat_summary(fun.data=median_hilow) +
      labs(title = "Observation 3") +
      theme(plot.title = element_text(hjust = 0.5), legend.position = 
      'none')


library(gridExtra)
get_legend<-function(myggplot){
 tmp <- ggplot_gtable(ggplot_build(myggplot))
 leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
 legend <- tmp$grobs[[leg]]
 return(legend)
    }


# Save legend

legend <- get_legend(g1)


# Remove legend from 1st graph

g1 <- g1 + theme(legend.position = 'none')

# Combine graphs

grid.arrange(g1, g2, g3, legend, ncol=4, widths=c(2.3, 2.3, 2.3, 0.8))

您可以在此过程中进行许多其他小的调整