【问题标题】:Creating stacked chart创建堆积图
【发布时间】:2015-05-27 10:38:48
【问题描述】:

我有两个存储用户登录尝试的表。一个表包含所有成功登录,另一个包含失败尝试。我正在尝试通过使用失败登录计数和成功登录计数来创建堆叠图表。这就是我的表格的样子:

Success_login 表:

User_ID  Site_Address  Login_Attempts
1        xxx.xxx.xxx   5
2        xxx.xxy.yyy   10

Fail_login 表:

User_ID  Site_Address  Login_Attempts
1        xxx.xxx.xxx   2
2        xxx.xxy.yyy   8

如何使用这两个表的 Login_Attempts 列来创建堆积图,以便突出显示成功和失败尝试?我上网查了一下,找到了这段代码:

# Stacked Bar Plot with Colors and Legend
 counts <- table(mtcars$vs, mtcars$gear)
 barplot(counts, main="Car Distribution by Gears and VS",
 xlab="Number of Gears", col=c("darkblue","red"),
 legend = rownames(counts))

但是,它不起作用,因为我的两个表有不同数量的记录。如果您能指导我找到解决方案,我将不胜感激。

谢谢

【问题讨论】:

  • 请提供a reproducible example,其中包含可重现格式的数据(例如,通过在您的问题中包含dput 的输出)。

标签: r stacked-chart


【解决方案1】:

讨论

首先,您必须将数据统一到一个表中。如果您熟悉 SQL,这可以通过一种外连接来完成。见How to join (merge) data frames (inner, outer, left, right)?。生成的NAs(对于未能加入对面表的记录)必须用零替换,以便对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%。 (不幸的是,您必须根据输入数据手动计算,但正如我所说,这是包中的一个弱点。)

另外,关于我对条形单一性的评论,堆叠条形图更常见的是用于比较多个条形,而不是显示单个条形。 (这就是为什么我最初的假设是您希望每个用户/站点都有一个单独的条形图。)通常您会看到一个普通的旧条形图并排显示不同的数据点,而不是单个堆叠的条形图。但这确实取决于您的应用程序,因此请选择最适合您的方法。

【讨论】:

  • 谢谢!我应该清除但我正在寻找的是比较所有用户的成功和失败的总数。不是个人用户。所以只会有一个条堆叠在另一个之上。我使用 rowSums 来总结您的数据“barplot(rowSums(stackData)...”但结果是两个条形图。知道为什么吗?
  • 谢谢!!你能解释一下为什么你认为创建单条堆叠条很奇怪吗?有没有办法扩展 y 轴使其包含条形?
【解决方案2】:
  1. 尝试手动绘制您尝试创建的堆叠图表。它甚至有意义吗?
  2. 当您确信您现在知道您想要的结果应该是什么样子时,请手动创建一个 single data.frame 或矩阵,以便barplot 创建您的结果。请记住包括特殊情况,例如用户只有成功或不成功的登录。
  3. 了解如何将您的输入 data.frames 放在上一步中的单个 data.frame 中。

第 2 步的结果是您在此处提出合理问题所需的可重现示例。 第 3 步是您在此处提出的问题,但您似乎不确定中间结果应该是什么样子。 第 1 步是关于最终产品的可视化,然后从那里开始工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 2013-05-28
    相关资源
    最近更新 更多