R ggplot2跨数据框实现柱状图(geom_bar)叠加折线图(geom_line)报错修复
ggplot2跨数据框叠加折线图层报错修复及多系列匹配方案
报错原因
报错由两处写法错误直接导致:
geom_*系列图层参数顺序错误:geom_line第一个入参为mapping(必须是aes()生成的映射对象),第二个入参才是data。原代码直接将dat.m2数据框放在第一个参数位,函数将数据框识别为映射对象校验,直接触发报错。- 映射列名不匹配:原代码对
dat2做了熔融操作生成dat.m2,这个数据框不存在x、y3列,只有和柱状图数据一致的Year、variable、value三个字段,就算参数顺序正确,列名错误也无法正常渲染。
另外原代码同时加载reshape和reshape2包,两个包的melt函数存在命名冲突,有潜在运行风险,保留reshape2即可。
单折线叠加修复代码
调整geom_line的参数顺序,匹配正确的列名,同时加上group=1映射避免数值型x轴导致的连线失败:
library(zoo) library(ggplot2) library(reshape2) x <- c(2000,2001,2002,2003,2004) y1 <- c(41,62,71,316,172) y2 <- c(3018,2632,2643,2848,2738) y3 <- c(3065,2709,2721,3192,2925) dat1 <- data.frame(Year=x, y1, y2) dat.m1 <- melt(dat1, id.vars='Year') dat2 <- data.frame(Year=x, y3) dat.m2 <- melt(dat2, id.vars='Year') b <- ggplot(dat.m1, aes(Year, value)) + geom_bar(width=0.6, aes(fill = variable), stat = "identity")+ # 显式指定data参数,映射使用熔融后的字段名,加group=1保证连线正常 geom_line(mapping = aes(group=1), data = dat.m2, size = 1.5, color="red") + xlab("Year") + ylab("Water Depth (mm)")+ theme(legend.position="top")+ theme(panel.background = element_rect(fill = 'white', colour = 'black'))+ theme(axis.text=element_text(size=13),axis.title=element_text(size=14))+ theme(legend.text=element_text(size=14))+ theme(plot.margin=unit(c(0.2,0.7,0.5,0.2),"cm"))+ guides(fill = guide_legend(title="", title.position="top", direction="horizontal")) b
柱形与折线一一匹配实现方法
如果需要给每个柱形系列搭配对应折线,不需要拆分多个数据框,直接将所有变量整合为一个长表,在每个图层中筛选需要展示的数据即可,还能自动统一图例样式:
# 整合所有年度数据统一做长表转换 dat_all <- data.frame(Year=x, y1, y2, y3) dat.m_all <- melt(dat_all, id.vars = 'Year') c <- ggplot(dat.m_all, aes(x=Year, y=value)) + # 柱状图图层筛选需要展示为柱的变量 geom_bar(data = subset(dat.m_all, variable %in% c("y1","y2")), width=0.6, stat="identity", aes(fill=variable), position = "dodge") + # 折线图层筛选需要展示为线的变量,多折线时按variable分组即可 geom_line(data = subset(dat.m_all, variable == "y3"), size=1.5, aes(color=variable, group=variable)) + # 可自定义配色区分柱、线系列 scale_fill_brewer(palette = "Set2", name="柱形指标") + scale_color_manual(values = c("y3"="#d62728"), name="折线指标") + xlab("Year") + ylab("Water Depth (mm)")+ theme(legend.position="top", panel.background = element_rect(fill = 'white', colour = 'black'), axis.text=element_text(size=13), axis.title=element_text(size=14), legend.text=element_text(size=14), plot.margin=unit(c(0.2,0.7,0.5,0.2),"cm")) c
注意事项
- 记不住
geom_*图层参数顺序时,一律显式写data =、mapping =指定参数,避免顺序错误 - x轴为数值型年份时,折线图层必须指定
group映射,否则ggplot无法正确识别分组,会出现连线失败的问题 - 功能重复的R包不要同时加载,避免函数冲突导致的奇怪报错
内容的提问来源于stack exchange,提问作者Salam Abbas
相关产品推荐
相关产品推荐

