【问题标题】:Gantt style time line plot (in base R)甘特式时间线图(以 R 为底)
【发布时间】:2012-03-25 17:53:53
【问题描述】:

我有一个如下所示的数据框:

       person n start end
1         sam 6     0   6
2        greg 5     6  11
3     teacher 4    11  15
4         sam 4    15  19
5        greg 5    19  24
6       sally 5    24  29
7        greg 4    29  33
8         sam 3    33  36
9       sally 5    36  41
10 researcher 6    41  47
11       greg 6    47  53

其中 start 和 end 是时间或持续时间(sam speak 从 0 到 6;greg 从 6 到 11 等)。 n 是这个人说话的时长(在这种情况下是词数)。我想将其绘制为基础 R 中的时间线(我最终可能会使用 ggplot2 提出类似的问题,但这个答案是特定于基础 R [当我说基础时,我指的是标准安装附带的软件包])。

y 轴是人,x 轴是时间。希望最终产品对于上面的数据看起来像这样:

我想使用 base R 来做这个。我不知道如何解决这个问题。我的想法是使用点图并绘制点图但忽略点。然后用方形端段检查这个。我不确定这将如何工作,因为段需要数字 x 和 y 点来制作段,并且 y 轴是分类的。另一个想法是将因子转换为数字(为每个因子分配一个数字)并绘制为空白散点图,然后使用方形端线段进行遍历。这可能是我所在领域查看语音模式的强大工具。

提前感谢您的帮助。

PS 方端线段的参数是 segments(... , lend=2) 以节省那些不熟悉所有线段参数的人查找此信息的时间。

【问题讨论】:

    标签: r


    【解决方案1】:

    你说你想要一个基本的 R 解决方案,但你没有说为什么。由于这是ggplot 中的一行代码,所以我还是展示了这一点。

    library(ggplot2)
    ggplot(dat, aes(colour=person)) + 
        geom_segment(aes(x=start, xend=end, y=person, yend=person), size=3) +
        xlab("Duration")
    

    【讨论】:

    • 听起来他已经避免了他正​​在开发的包的所有其他外部依赖项,并试图保持这种方式:stackoverflow.com/questions/9857787/…
    • 他也可能想要更多地控制外观,更好地理解基础图形,将其与其他基础图形绘图集成,或者只是有偏好。哦,这真的不是一行。您那里至少有 2 行,很容易解释为 3,而您忘记了 install.packages('ggplot2')。
    • @Andrie,非常好。我不想使用 ggplot 的原因是正如 Chase 所指出的,我已经避免了除 wordcloud 之外的所有依赖项(因为这个包在 C 中进行了一些我无法做的编码)。话虽如此,该函数将进行绘图,但还将返回一个可以提供给 ggplot 的已处理数据帧(我计划在我的包中将其作为示例显示,尽管可能必须使用# 来获取代码以通过包创建测试。我对 ggplot 感兴趣的原因是因为我将使用相同的想法进行重复测量,并且在这里分面会很好。干得好安德烈。+1
    • @TylerRinker 不错。您有两个选项可以在不引入依赖项的情况下将其包含在包中。 1) 使用dontruncran.r-project.org/doc/manuals/… 2) 在您的包DESCRIPTION 中使用suggests(ggplot2),然后在您的示例中使用require(ggplot2)。这样,ggplot2 包只有在用户真正想要使用它时才会被加载。
    • @Andrie 谢谢,这是我第一个供一般消费者使用的包(我之前为自己创建了 2 个包,但对于第一个计时器,我会尽可能自律)并希望提供我可以的产品。感谢您的依赖 vs 建议信息 +1
    【解决方案2】:

    和@John 的做法很像,不过既然做了,我就贴出来吧:)

    这是一个绘制甘特图的通用函数(无依赖关系):

    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],na.rm=T)
      maxval <- max(data[,end.col],na.rm=T)
    
      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.1
        yBottom <- i-0.1
        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(mar=op) # reset the plotting margins
    }
    

    使用示例:

    data <- read.table(text=
    '"person","n","start","end"
    "sam",6,0,6
    "greg",5,6,11
    "teacher",4,11,15
    "sam",4,15,19
    "greg",5,19,24
    "sally",5,24,29
    "greg",4,29,33
    "sam",3,33,36
    "sally",5,36,41
    "researcher",6,41,47
    "greg",6,47,53',sep=',',header=T)
    
    plotGantt(data, res.col='person',start.col='start',end.col='end',
              res.colors=c('green','blue','brown','red','yellow'))
    

    结果:

    【讨论】:

    • 这个答案也符合我列出的参数。它看起来也很棒。谢谢分享,方法略有不同。 +1
    • 也感谢您提供甘特图。我不知道它叫什么。
    • @TylerRinker:不客气 :)。不过,我稍微更改了代码,以便为标签腾出空间。
    • 我想将其中的一些作品包含在一个包中。我想正确地引用你。你能联系我@tyler.rinker@gmail.com
    • @TylerRinker:谢谢,但没有必要为这段小代码引用我。随意使用它;)
    【解决方案3】:

    虽然 y 轴是分类的,但您只需为类别 (1:5) 分配数字并跟踪它们。使用因子的默认 as.numeric() 通常会按字母顺序对它们进行编号,但您还是应该检查一下。使用 xaxt = 'n' 参数制作你的情节。然后使用axis()命令放入一个y轴。

    axis(2, 1:5, myLabels)
    

    请记住,无论何时您在绘制地图时,唯一的放置方式就是使用数字。分类 x 或 y 值始终只是数字 1:nCategories 用类别名称标签代替轴上的数字。

    类似下面的内容让你足够接近(假设你的 data.frame 对象被称为 datf)...

    datf$pNum <- as.numeric(datf$person)
    plot(datf$pNum, xlim = c(0, 53), type = 'n', yaxt = 'n', xlab ='Duration (words)', ylab = 'person', main = 'Speech Duration')
    axis(2, 1:5, sort(unique(datf$person)), las = 2, cex.axis = 0.75)
    with(datf, segments(start, pNum, end, pNum, lwd = 3, lend=2))
    

    【讨论】:

    • 非常好。这非常接近我要求的(在基本参数内),我可以从这里获取它。非常好的工作。
    • 希望您不要介意,但我将代码 , lend=2 放入您的 segments 使用中。
    • 要添加结果图片吗?
    猜你喜欢
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 2010-11-03
    • 2021-05-10
    相关资源
    最近更新 更多