【发布时间】:2014-10-15 04:07:05
【问题描述】:
我想问一个与这篇文章 [Gantt style time line plot (in base R)] 中给出的答案有关的后续问题,该问题是基于 r 的甘特图。我觉得这值得提出一个新问题,因为我认为这些情节具有广泛的吸引力。我也希望一个新问题能引起更多关注。我也觉得我需要比那个问题的 cmets 更多的空间来具体说明。
以下代码由@digEmAll 提供。它需要一个数据框,其中的列表示开始时间、结束时间和分组变量,并将其转换为甘特图。我稍微修改了 @digEmAll 的函数,以使甘特图中的条形图/线段彼此相邻,而不是有间隙。这里是:
plotGantt <- function(data, res.col='resources',
start.col='start', end.col='end', res.colors=rainbow(30))
{
#slightly enlarge Y axis margin to make space for labels
op <- par('mar')
par(mar = op + c(0,1.2,0,0))
minval <- min(data[,start.col])
maxval <- max(data[,end.col])
res.colors <- rev(res.colors)
resources <- sort(unique(data[,res.col]),decreasing=T)
plot(c(minval,maxval),
c(0.5,length(resources)+0.5),
type='n', xlab='Duration',ylab=NA,yaxt='n' )
axis(side=2,at=1:length(resources),labels=resources,las=1)
for(i in 1:length(resources))
{
yTop <- i+0.5
yBottom <- i-0.5
subset <- data[data[,res.col] == resources[i],]
for(r in 1:nrow(subset))
{
color <- res.colors[((i-1)%%length(res.colors))+1]
start <- subset[r,start.col]
end <- subset[r,end.col]
rect(start,yBottom,end,yTop,col=color)
}
}
par(op) # reset the plotting margins
}
以下是一些示例数据。你会注意到我有四个组 1-4。但是,并非所有数据帧都具有所有四个组。有的只有两个,有的只有三个。
mydf1 <- data.frame(startyear=2000:2009, endyear=2001:2010, group=c(1,1,1,1,2,2,2,1,1,1))
mydf2 <- data.frame(startyear=2000:2009, endyear=2001:2010, group=c(1,1,2,2,3,4,3,2,1,1))
mydf3 <- data.frame(startyear=2000:2009, endyear=2001:2010, group=c(4,4,4,4,4,4,3,2,3,3))
mydf4 <- data.frame(startyear=2000:2009, endyear=2001:2010, group=c(1,1,1,2,3,3,3,2,1,1))
这里我运行了上面的函数,但是指定了四种颜色进行绘图:
plotGantt(mydf1, res.col='group', start.col='startyear', end.col='endyear',
res.colors=c('red','orange','yellow','gray99'))
plotGantt(mydf2, res.col='group', start.col='startyear', end.col='endyear',
res.colors=c('red','orange','yellow','gray99'))
plotGantt(mydf3, res.col='group', start.col='startyear', end.col='endyear',
res.colors=c('red','orange','yellow','gray99'))
plotGantt(mydf4, res.col='group', start.col='startyear', end.col='endyear',
res.colors=c('red','orange','yellow','gray99'))
这些是地块:
我想做的是修改函数,以便:
1) 它将在 y 轴上绘制所有四个组,无论它们是否实际出现在数据中。
2) 无论有多少组,每个绘图的每个组都具有相同的颜色。如您所见,mydf2 有四个组,并且绘制了所有四种颜色(1-红色、2-橙色、3-黄色、4-灰色)。这些颜色实际上是使用与 mydf3 相同的组绘制的,因为它只包含组 2、3、4,并且颜色是按相反的顺序选择的。但是 mydf1 和 mydf4 为每个组绘制了不同的颜色,因为它们没有任何第 4 组。灰色仍然是第一个选择的颜色,但现在它用于最低出现的组(mydf1 中的 group2 和 mydf3 中的 group3)。
在我看来,我需要处理的主要事情是函数内部的向量“资源”,并且不仅包含唯一组,而且包含所有组。当我尝试手动覆盖以确保它包含所有组时,例如做一些像resources <-as.factor(1:4) 这样简单的事情然后我得到一个错误:
'Error in rect(start, yBottom, end, yTop, col = color) : cannot mix zero-length and non-zero- length coordinates'
大概for循环不知道如何为不存在的组绘制不存在的数据。
我希望这是一个可复制/可读的问题,并且很清楚我想要做什么。
编辑:我意识到要解决颜色问题,我可以为每个示例 dfs 中存在的 3 个组指定颜色。但是,我的意图是将此图用作函数的输出,如果所有组都存在于特定 df,则不会提前知道它。
【问题讨论】:
-
“base R”中没有甘特图。最接近的是
gantt.chart包 plotrix。 -
@BondedDust 你读过第一句话吗?
-
我做到了。我提供了一个实现的参考。请求一个能够“知道”没有被传递给它的对象的函数似乎是荒谬的。
-
我会修改这个问题,因为它不是最小的。现在你已经包含了太多的代码和信息,如果不花大量时间解析问题,就很难弄清楚你想要什么。