R语言保留含缺失值原数据结构绘制折线图的方法
问题:保留完整数据结构前提下用ggplot2绘制折线图
现有如下tibble数据集:
df=tibble::tibble( treatment = rep(c("A", "B", "C"), each = 51L), day = rep(seq(0, 50, by = 1), 3), mean = rep( c( 0, NA, 6.75, NA, 24.75, NA, 35.75, NA, 0, NA, 0.75, NA, 2.5, NA, 4.5, NA, 0, NA, 0.5, NA, 3.25, NA, 3.75, NA ), rep(c(1L, 34L, 1L, 6L, 1L, 3L, 1L, 4L), 3) ), std_error = rep( c( 0, NA, 1.887458608817687, NA, 5.02286438863988, NA, 8.178987304876646, NA, 0, NA, 0.4787135538781691, NA, 1.040832999733066, NA, 1.755942292142123, NA, 0, NA, 0.2886751345948129, NA, 1.436140661634507, NA, 1.25, NA ), rep(c(1L, 34L, 1L, 6L, 1L, 3L, 1L, 4L), 3) ), )
使用以下ggplot2代码绘制时,geom_line无法生成线条:
library(ggplot2) ggplot(data=df, aes(x=as.numeric(day), y=mean, fill=treatment, shape=treatment, color=treatment)) + geom_errorbar(aes(ymin=mean-std_error, ymax=mean+std_error), position=position_dodge(0.7), width=3, color="grey35") + geom_line(aes(color=treatment), size=0.5) + geom_point(size=5, stroke=1, color="white") + scale_shape_manual(values=c(21,22,24)) + scale_fill_manual(values=c("red","grey55", "grey15")) + scale_color_manual(values=c("red","grey55", "grey15")) + scale_x_continuous(breaks=seq(0,50,10),limits=c(0,50)) + scale_y_continuous(breaks=seq(0,50,10),limits=c(0,50)) + theme_classic(base_size=20, base_family="serif") + theme(legend.position=c(0.15,0.85), legend.title=element_blank(), legend.key=element_rect(color="white", fill="white"), legend.text=element_text(family="serif", face="plain", size=13, color= "Black"), legend.background=element_rect(fill=alpha(0.5)), axis.line=element_line(linewidth=0.5, colour="black"))+ windows(width=5, height=5.5)
删除缺失值后可正常绘图,但需要保留原始0-50天的完整数据结构用于后续补充数据,如何解决?
解决方案
无需修改原始数据集,只需为geom_line单独指定过滤掉缺失值的子集即可。ggplot2允许每个图层使用不同的数据,这样既保留了原始数据结构,又能让线条连接所有存在有效值的点。
修改后的完整代码如下:
library(ggplot2) library(dplyr) ggplot(data=df, aes(x=as.numeric(day), y=mean, fill=treatment, shape=treatment, color=treatment)) + geom_errorbar(aes(ymin=mean-std_error, ymax=mean+std_error), position=position_dodge(0.7), width=3, color="grey35") + # 仅为geom_line提供无缺失值的数据 geom_line(data = df %>% filter(!is.na(mean)), aes(color=treatment), size=0.5) + geom_point(size=5, stroke=1, color="white") + scale_shape_manual(values=c(21,22,24)) + scale_fill_manual(values=c("red","grey55", "grey15")) + scale_color_manual(values=c("red","grey55", "grey15")) + scale_x_continuous(breaks=seq(0,50,10),limits=c(0,50)) + scale_y_continuous(breaks=seq(0,50,10),limits=c(0,50)) + theme_classic(base_size=20, base_family="serif") + theme(legend.position=c(0.15,0.85), legend.title=element_blank(), legend.key=element_rect(color="white", fill="white"), legend.text=element_text(family="serif", face="plain", size=13, color= "Black"), legend.background=element_rect(fill=alpha(0.5)), axis.line=element_line(linewidth=0.5, colour="black"))+ windows(width=5, height=5.5)
原理说明
- 原始代码中
geom_line使用了包含大量NA的完整数据集,ggplot2默认不会连接被NA分隔的点,因此无法生成可见线条。 - 通过为
geom_line的data参数传入过滤后的子集(仅保留mean非NA的行),让线条仅连接存在有效值的观测点,同时其他图层(如geom_errorbar、geom_point)仍使用原始数据集,自动忽略NA值仅显示有数据的点。 - 原始数据集的结构完全保留,不影响后续补充0-50天的数据操作。
内容的提问来源于stack exchange,提问作者J.K Kim
相关产品推荐
相关产品推荐

