我每个月都会为我们的高级领导撰写一份报告-它显示了I.T.性能。诸如事件解决,系统可用性等方面的信息。我一直在寻找方法来可视化我拥有的一些数据,并找到了漂亮的表示形式,如下所示:
我喜欢这种布局。我所有的报告都在RMarkdown中与一些混合LaTex一起使用。我一直在考虑如何在Rmarkdown中复制这样的内容,或者甚至只是使用嵌入在我的markdown文件中的原始LaTex ...我已经知道我可以使用sparklines包来获取sparklines,可以从中获取值和标题数据。我唯一的旅行就是整个事情。
我可以在ggplot中做类似的事情吗?或者也许使用晶格...我迷失了如何将所有这些放在一起。
一些基本信息-我的数据集是R数据框。每行包含一个不同的系统或指标。将有一系列包含效果的列(计数和百分比)。我设想了某种循环,它将构建每个框,然后以某种方式将其全部放入网格中。
如果需要,我可以提供样本数据集,但是它们是非常基本的。字段/列类似于:名称,目标,2018年1月,2018年2月等。如果某些指标同时需要计数和百分比,则可能每个月都有包含计数和百分比的列。
关于如何重现此事的任何想法?
样本数据:
这是示例数据集。我希望迷你图成为百分比,但我也有每月的工作时间。显示的数字可以是年初至今的小时数和年初至今的百分比。抱歉,对于较晚的数据集-我必须进行清理才能删除机密信息。我已经添加了CSV和RData格式。再次感谢!
答案 0 :(得分:2)
这个问题有很多部分,我同意这样的意见,即确切的解决方案将取决于许多细节。但是,假设您正在寻找一种可以创建某种形式的静态仪表板的解决方案,则可以使用经过大量编辑的ggplot构建与此类似的内容。
我已经编写了一个函数metricplot
,可以轻松创建许多此类较小的图表。它具有以下变量:
功能如下:
#' Make a small metric plot
#'
#'
metricplot <- function(df, x, y, title, colour){
# Find the change in values
start <- df[[y]][1]
end <- df[[y]][length(df)]
change <- scales::percent((end - start)/start)
plot <-
ggplot(df) +
annotate("rect", xmin = -Inf, xmax = Inf, ymax = max(df[[y]] - 1),
ymin = min(df[[y]]), fill = "white", alpha = 0.5) +
geom_line(aes_string(x, y), colour = "white", size = 2) +
labs(title = title,
subtitle = paste0(end, " / ", change)) +
theme(axis.line=element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),legend.position="none",
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
plot.background = element_rect(fill = colour),
plot.title = element_text(size = 20, colour = "white", face = "plain"),
plot.subtitle = element_text(size = 40, colour = "white", face = "bold"))
return(plot)
}
将此功能与示例数据集结合使用:
set.seed(123)
df2 <- data.frame(x = 1:20,
y = c(9, rep(10, 17), 12, 14),
z = c(14, rep(10, 17), 12, 11))
library(ggplot2)
library(ggthemes)
grid.arrange(metricplot(df2, "x", "y", "Metric 1", "#fc8d59"),
metricplot(df2, "x", "y", "Metric 1", "#91cf60"),
metricplot(df2, "x", "z", "Something Else", "#999999"),
metricplot(df2, "x", "z", "One More", "#fc8d59"), ncol=4)
很明显,这已经对数据的格式做了一些假设,但希望它可以使您朝着正确的方向前进:)
答案 1 :(得分:1)
我已经从下面的示例代码重写了@ mikey-harper的答案中的第一部分代码。这修改了他的代码以使用我的数据集格式。仍然需要进行一些调整才能获得我想要的格式,但就目前而言,这是一个良好的开端。只是想发布我的进度。
# Needed Libraries
library(Hmisc)
library(zoo)
library(lubridate)
library(ggplot2)
library(ggthemes)
library(grid)
library(gridExtra)
# Plot Function
metricplot <- function(data = criticalSystemAvailabilityFullDetail, row = 1) {
# Since data is organized by row, I need to pull only the columns I need
# for the particular row (system) specificied. Then turn it into columns
# since ggplot works best this way.
ytdMonths <- as.data.frame(names(data)[4:((month(Sys.Date())-1)+3)])
ytdValue <- t(as.data.frame(data[row,((month(Sys.Date()))+3):(ncol(data)-2)][1,]))
ytdData <- cbind(ytdMonths, ytdValue)
names(ytdData)[1] <- "Month"
names(ytdData)[2] <- "Value"
# Since I need red, yellow and green for my thresholds, I already have my
# target. My rules for this are basically, green until it exceeds 50%
# of the target, then it turns yellow. Once it exceeds the Target, it turns
# red. This function is called when the plot is made to determine the background
# color.
colour <- function (system = data[row,]) {
if(data[row,ncol(data)] < as.numeric(strsplit(data[row,2], "%")[[1]][1]) ) {
return("#fc5e58")
} else if((data[row,ncol(data)] > as.numeric(strsplit(data[row,2], "%")[[1]][1])) == TRUE & (data[row,ncol(data)] < ((as.numeric(strsplit(data[row,2], "%")[[1]][1]) + 100.00) / 2)) == TRUE) {
return("#ebc944")
} else {
return("#8BC34A")
}
}
# Now for the plot. I have made some slight modifications to this. For example, in the white area that
# represents the high and low - I have used 100% for the max and the target for the low. I do this dynamically
# by using the target from the row (system) I am currently plotting. I adjusted the line size down to 1, since
# the preivous value made the line a little too big.
plot <-
ggplot(ytdData) +
annotate("rect", xmin = -Inf, xmax = Inf, ymax = 100.000, ymin = as.numeric(strsplit(data[row,2], "%")[[1]][1]), fill = "white", alpha = 0.6) + # Create the plot
geom_line(aes(x = as.yearmon(Month), y = Value), colour = "white", size = 1) +
labs(title = data[row,1], subtitle = paste0(data[row,ncol(data)], "% / ", data[row,(ncol(data)-1)], " hours")) + # Add title and subtitle
theme(axis.line=element_blank(), # Remove X-axis title
axis.text.x=element_blank(), # Remove X-Xais Text
axis.text.y=element_blank(), # Remove Y-Axis Text - Comment this whole line out if you want a scale on the y-axis.
axis.ticks=element_blank(), # Remove X-Axis
axis.title.x=element_blank(), # Remove X-Axis Titlke
axis.title.y=element_blank(),legend.position="none", # Remove legend and Y-axis title
panel.background=element_blank(), # Remove bland gray background
panel.border=element_blank(), # Remove border
panel.grid.major=element_blank(), # Remove Grid
panel.grid.minor=element_blank(), # Remove Grid
plot.background = element_rect(fill = colour()), # Red, Green, Yellow
plot.title = element_text(size = 10, colour = "white", face = "plain"), # Main Title
plot.subtitle = element_text(size = 15, colour = "white", face = "bold"))
return(plot) # Return the plot.
}
# Now we build the the grid by calling each row. Depending on the size of the canvas,
# you might want to break up how many rows on the grid you do. In my case, this
# is going on an A4 size peice of paper, so I will probably limit it to about 5-6 rows
# in order to provide a readable page. Squeezing 5 columns in could get you more
# on a page, too.
grid.arrange(metricplot2(data = criticalSystemAvailabilityFullDetail, row=1),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=2),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=3),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=4),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=5),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=5),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=7),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=8),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=9),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=10),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=11),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=12),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=13),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=14),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=15),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=16),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=17),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=18),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=19),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=20),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=21),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=22),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=23),
metricplot2(data = criticalSystemAvailabilityFullDetail, row=24), ncol=4)
我唯一想念的是如何减少小时数(字幕的第二部分)。我不知道我是否可以使用第3个字幕,但需要尝试一下。否则,我需要弄清楚如何在字幕中使用不同的大小。否则,这似乎可以正常工作。