讨论
首先,您必须将数据统一到一个表中。如果您熟悉 SQL,这可以通过一种外连接来完成。请参阅如何加入(合并)数据帧(内部、外部、左侧、右侧)?. 结果NA
s (对于未能加入对面表的记录)必须用零替换,以便最终调用barplot()
工作。
然后,您必须barplot()
以生成堆叠条形图所需的格式导出矩阵,只需调用matrix()
. 注意正确设置标签/标题/图例/颜色,您可以获得漂亮的堆叠条形图:
代码
s <- data.frame(User_ID=c(1,2,3), Site_Address=c('xxx.xxx.xxx','xxx.xxy.yyy','xxx.yyy.zzz'), Login_Attempts=c(5,10,3) );
f <- data.frame(User_ID=c(1,2,4), Site_Address=c('xxx.xxx.xxx','xxx.xxy.yyy','xxx.yyy.zzz'), Login_Attempts=c(2,8,4) );
all <- merge(s,f,by=c('User_ID','Site_Address'),suffixes=c('.successful','.failed'),all=T);
all[is.na(all)] <- 0;
stackData <- matrix(c(all$Login_Attempts.failed, all$Login_Attempts.successful ),2,byrow=T);
colnames(stackData) <- paste0(all$User_ID, '@', all$Site_Address );
rownames(stackData) <- c('failed','successful');
barplot(stackData,main='Successful and failed login attempts',xlab='User_ID@Site_Address',ylab='Login_Attempts',col=c('red','blue'),legend=rownames(stackData));
结果数据
r> s;
User_ID Site_Address Login_Attempts
1 1 xxx.xxx.xxx 5
2 2 xxx.xxy.yyy 10
3 3 xxx.yyy.zzz 3
r> f;
User_ID Site_Address Login_Attempts
1 1 xxx.xxx.xxx 2
2 2 xxx.xxy.yyy 8
3 4 xxx.yyy.zzz 4
r> all;
User_ID Site_Address Login_Attempts.successful Login_Attempts.failed
1 1 xxx.xxx.xxx 5 2
2 2 xxx.xxy.yyy 10 8
3 3 xxx.yyy.zzz 3 0
4 4 xxx.yyy.zzz 0 4
r> stackData;
1@xxx.xxx.xxx 2@xxx.xxy.yyy 3@xxx.yyy.zzz 4@xxx.yyy.zzz
failed 2 8 0 4
successful 5 10 3 0
输出
参考
编辑:创建一个单条堆叠条形图有点奇怪,但是好的,这是你可以做到的,使用上面的数据(all
)作为基础:
barplot(matrix(c(sum(all$Login_Attempts.failed),sum(all$Login_Attempts.successful))),main='Successful and failed login attempts',ylab='Login_Attempts',col=c('red','blue'),legend=c('failed','successful'));
编辑:是的,默认情况下y轴应该完全覆盖堆栈,这是基础图形包中的一个弱点,它没有。您可以将ylim=c(0,1.2*sum(do.call(c,all[,3:4])))
作为参数添加到barplot()
调用中,以强制 y 轴超出堆栈的最高点至少 20%。(不幸的是,您必须从输入数据中手动计算,但正如我所说,这是包中的一个弱点。)
此外,关于我对条形图单一性的评论,堆叠条形图更常见的是用于比较多个条形图,而不是显示单个条形图。(这就是为什么我最初的假设是您希望每个用户/站点都有一个单独的条形图。)通常您会看到一个普通的旧条形图并排显示不同的数据点,而不是单个堆叠条形图。但这真的取决于你的应用程序,所以做最适合你的。