ggplot绘制含NA值连续折线图及添加次Y轴报错求助
问题解决步骤
1. 解决charToDate报错
该报错是as.Date()函数无法自动识别Date列的所有日期格式导致的,并非na.omit的问题,修改日期转换代码、主动指定格式即可:
# 转换时指定标准年月日格式,转换失败的值会自动设为NA test$Date <- as.Date(test$Date, format = "%Y-%m-%d")
如果还有报错,可以运行which(is.na(test$Date))查看转换失败的行,修正对应日期格式即可。
2. 解决折线不连续问题
你之前对整个数据集用na.omit()是错误的:你的数据中每行只有A或B其中一列有值,na.omit会删除所有含NA的行,最终数据集会被清空。
要让折线连续,只需要给每个序列单独筛选对应y列非NA的行,无需删除整行数据:
- 绘制A序列的折线时,筛选A非NA的行
- 绘制B序列的折线时,筛选B非NA的行
3. 修正双Y轴代码
你的附加代码存在3个问题:
- 重复定义
scale_y_continuous会导致前面的配置被覆盖,需要合并为一个 - B的缩放系数不合理:原代码用
B/20,缩放后的值远低于主Y轴28-31的范围,会完全看不到 - 没有给B序列的geom_point指定y映射,会默认继承A的y值
修正后的完整代码如下:
library(ggplot2) library(scales) test <- read.csv( file = "testdata.csv", stringsAsFactors = FALSE ) # 修正日期转换报错 test$Date <- as.Date(test$Date, format = "%Y-%m-%d") ggplot(test, aes(x = Date)) + # 绘制A序列的折线和点,仅用A非NA的数据保证连续 geom_line(data = test[!is.na(test$A),], aes(y = A, colour = "A"), na.rm = TRUE) + geom_point(data = test[!is.na(test$A),], aes(y = A), shape = 1) + # 绘制B序列的折线和点,调整缩放系数让B值落在主Y轴范围内,这里用B*10+28适配28-31的区间 geom_line(data = test[!is.na(test$B),], aes(y = B*10 + 28, colour = "B"), na.rm = TRUE) + geom_point(data = test[!is.na(test$B),], aes(y = B*10 + 28), shape = 0) + xlab("") + ylab("A") + scale_x_date(breaks = date_breaks("1 month"), labels = date_format("%b")) + # 合并Y轴配置,第二轴按缩放规则反向转换 scale_y_continuous( expand = c(0, 0), limits = c(27.5, 31), # 放宽下限适配示例中27.6的A值,不需要可改回28 sec.axis = sec_axis(~(. - 28)/10, name = "B") ) + scale_color_manual(values = c("A" = "black", "B" = "red")) + theme_bw()
如果你的B值范围和示例不同,可自行调整缩放系数:比如B最大值为max_B,要让它落到主Y轴上限31,缩放公式为 y = B * (31-28)/max_B +28,第二轴的反向公式对应改为 ~(. -28)*max_B/(31-28)即可。
内容的提问来源于stack exchange,提问作者okscientist
相关产品推荐
相关产品推荐

