Gráficos de Gantt com R

Respostas:

104

Existem agora algumas maneiras elegantes de gerar um gráfico de Gantt em R.

Usando Candela

library(candela)

data <- list(
    list(name='Do this', level=1, start=0, end=5),
    list(name='This part 1', level=2, start=0, end=3),
    list(name='This part 2', level=2, start=3, end=5),
    list(name='Then that', level=1, start=5, end=15),
    list(name='That part 1', level=2, start=5, end=10),
    list(name='That part 2', level=2, start=10, end=15))

candela('GanttChart',
    data=data, label='name',
    start='start', end='end', level='level',
    width=700, height=200)

insira a descrição da imagem aqui

Usando DiagrammeR

library(DiagrammeR)

mermaid("
gantt
dateFormat  YYYY-MM-DD
title A Very Nice Gantt Diagram

section Basic Tasks
This is completed             :done,          first_1,    2014-01-06, 2014-01-08
This is active                :active,        first_2,    2014-01-09, 3d
Do this later                 :               first_3,    after first_2, 5d
Do this after that            :               first_4,    after first_3, 5d

section Important Things
Completed, critical task      :crit, done,    import_1,   2014-01-06,24h
Also done, also critical      :crit, done,    import_2,   after import_1, 2d
Doing this important task now :crit, active,  import_3,   after import_2, 3d
Next critical task            :crit,          import_4,   after import_3, 5d

section The Extras
First extras                  :active,        extras_1,   after import_4,  3d
Second helping                :               extras_2,   after extras_1, 20h
More of the extras            :               extras_3,   after extras_1, 48h
")

insira a descrição da imagem aqui

Encontre este exemplo e muitos mais no DiagrammeR GitHub


Se os seus dados estiverem armazenados em a data.frame, você pode criar a string a ser transmitida mermaid(), convertendo-a no formato apropriado.

Considere o seguinte:

df <- data.frame(task = c("task1", "task2", "task3"),
                 status = c("done", "active", "crit"),
                 pos = c("first_1", "first_2", "first_3"),
                 start = c("2014-01-06", "2014-01-09", "after first_2"),
                 end = c("2014-01-08", "3d", "5d"))

#   task status     pos         start        end
#1 task1   done first_1    2014-01-06 2014-01-08
#2 task2 active first_2    2014-01-09         3d
#3 task3   crit first_3 after first_2         5d

Usando dplyre tidyr(ou qualquer um de seus recursos favoritos de troca de dados):

library(tidyr)
library(dplyr)

mermaid(
  paste0(
    # mermaid "header", each component separated with "\n" (line break)
    "gantt", "\n", 
    "dateFormat  YYYY-MM-DD", "\n", 
    "title A Very Nice Gantt Diagram", "\n",
    # unite the first two columns (task & status) and separate them with ":"
    # then, unite the other columns and separate them with ","
    # this will create the required mermaid "body"
    paste(df %>%
            unite(i, task, status, sep = ":") %>%
            unite(j, i, pos, start, end, sep = ",") %>%
            .$j, 
          collapse = "\n"
    ), "\n"
  )
)

Conforme mencionado por @GeorgeDontas nos comentários, existe um pequeno hack que poderia permitir alterar os rótulos do eixo x para datas em vez de 'w.01, w.02'.

Supondo que você salvou o gráfico da sereia acima m, faça:

m$x$config = list(ganttConfig = list(
  axisFormatter = list(list(
    "%b %d, %Y" 
    ,htmlwidgets::JS(
      'function(d){ return d.getDay() == 1 }' 
    )
  ))
))

Que dá:

insira a descrição da imagem aqui


Usando o timevis

Do timevis GitHub :

timevispermite que você crie visualizações de linha do tempo ricas e totalmente interativas em R. As linhas de tempo podem ser incluídas em aplicativos Shiny e documentos de marcação R, ou visualizadas no console R e no RStudio Viewer.

library(timevis)

data <- data.frame(
  id      = 1:4,
  content = c("Item one"  , "Item two"  ,"Ranged item", "Item four"),
  start   = c("2016-01-10", "2016-01-11", "2016-01-20", "2016-02-14 15:00:00"),
  end     = c(NA          ,           NA, "2016-02-04", NA)
)

timevis(data)

Que dá:

insira a descrição da imagem aqui


Usando plotly

Me deparei com este post fornecendo outro método usando plotly. Aqui está um exemplo:

library(plotly)

df <- read.csv("https://cdn.rawgit.com/plotly/datasets/master/GanttChart-updated.csv", 
               stringsAsFactors = F)

df$Start  <- as.Date(df$Start, format = "%m/%d/%Y")
client    <- "Sample Client"
cols      <- RColorBrewer::brewer.pal(length(unique(df$Resource)), name = "Set3")
df$color  <- factor(df$Resource, labels = cols)

p <- plot_ly()
for(i in 1:(nrow(df) - 1)){
  p <- add_trace(p,
                 x = c(df$Start[i], df$Start[i] + df$Duration[i]), 
                 y = c(i, i), 
                 mode = "lines",
                 line = list(color = df$color[i], width = 20),
                 showlegend = F,
                 hoverinfo = "text",
                 text = paste("Task: ", df$Task[i], "<br>",
                              "Duration: ", df$Duration[i], "days<br>",
                              "Resource: ", df$Resource[i]),
                 evaluate = T
  )
}

p

Que dá:

insira a descrição da imagem aqui

Você pode adicionar informações e anotações adicionais, personalizar fontes e cores etc. (consulte a postagem do blog para obter detalhes)

Steven Beaupré
fonte
É realmente bom. No entanto, parece-me bastante difícil criar automaticamente essa string que é passada para a sereia, usando dados armazenados em um dataframe.
George Dontas
É possível exibir datas como rótulos do eixo x, em vez de "w.01", "w.02" etc?
George Dontas
2
Substitua o gráfico de Gantt para permitir o eixo de data personalizado em vez da escala de 0-52
George Dontas,
O código funciona perfeitamente usando o DiagrameR e o Mermaid no Rstudio, mas ao usá-lo no PowerBI recebo um erro Mensagem de erro: Nenhuma imagem foi criada. O código R não resultou na criação de nenhum visual. Certifique-se de que seu script R resulte em um gráfico para o dispositivo R padrão. Qualquer ideia para alguém Obrigado Peddie
PeddiePooh
1
A solução com timevisem Rparece legal e simples. :-)
Suman Khanal
29

Um ggplot2gráfico de Gantt simples .

Primeiro, criamos alguns dados.

library(reshape2)
library(ggplot2)

tasks <- c("Review literature", "Mung data", "Stats analysis", "Write Report")
dfr <- data.frame(
  name        = factor(tasks, levels = tasks),
  start.date  = as.Date(c("2010-08-24", "2010-10-01", "2010-11-01", "2011-02-14")),
  end.date    = as.Date(c("2010-10-31", "2010-12-14", "2011-02-28", "2011-04-30")),
  is.critical = c(TRUE, FALSE, FALSE, TRUE)
)
mdfr <- melt(dfr, measure.vars = c("start.date", "end.date"))

Agora desenhe o gráfico.

ggplot(mdfr, aes(value, name, colour = is.critical)) + 
  geom_line(size = 6) +
  xlab(NULL) + 
  ylab(NULL)
Algodão rico
fonte
Eu só pude criar alguns dados duas vezes :-)
George Dontas
@ gd047: Isso exige uma palma da mão com as duas mãos. Idiotice agora corrigida.
Richie Cotton
1
É muito bom, mas o que estou procurando principalmente é uma maneira de mostrar mais de uma barra para cada tarefa (como você pode ver nos exemplos que dei), por exemplo, uma para a linha de base e outra para a duração real da tarefa. Existe uma maneira de fazer algo assim?
George Dontas
10

Considere usar o pacoteprojmanr (versão 0.1.0 lançada no CRAN em 23 de agosto de 2017).

library(projmanr)

# Use raw example data
(data <- taskdata1)

taskdata1:

  id name duration pred
1  1   T1        3     
2  2   T2        4    1
3  3   T3        2    1
4  4   T4        5    2
5  5   T5        1    3
6  6   T6        2    3
7  7   T7        4 4,5 
8  8   T8        3  6,7

Agora comece a preparar Gantt:

# Create a gantt chart using the raw data
gantt(data)

insira a descrição da imagem aqui

# Create a second gantt chart using the processed data
res <- critical_path(data)
gantt(res)

insira a descrição da imagem aqui

# Use raw example data
data <- taskdata1
# Create a network diagram chart using the raw data
network_diagram(data)

insira a descrição da imagem aqui

# Create a second network diagram using the processed data
res <- critical_path(data)
network_diagram(res)

insira a descrição da imagem aqui

user2030503
fonte
7

Experimente isto:

install.packages("plotrix")
library(plotrix)
?gantt.chart
Juur
fonte
5

Você pode fazer isso com o pacote GoogleVis :

datTL <- data.frame(Position=c(rep("President", 3), rep("Vice", 3)),
                    Name=c("Washington", "Adams", "Jefferson",
                           "Adams", "Jefferson", "Burr"),
                    start=as.Date(x=rep(c("1789-03-29", "1797-02-03", 
                                          "1801-02-03"),2)),
                    end=as.Date(x=rep(c("1797-02-03", "1801-02-03", 
                                        "1809-02-03"),2)))

Timeline <- gvisTimeline(data=datTL, 
                         rowlabel="Name",
                         barlabel="Position",
                         start="start", 
                         end="end",
                         options=list(timeline="{groupByRowLabel:false}",
                                      backgroundColor='#ffd', 
                                      height=350,
                                      colors="['#cbb69d', '#603913', '#c69c6e']"))
plot(Timeline)

insira a descrição da imagem aqui

Fonte: https://cran.r-project.org/web/packages/googleVis/vignettes/googleVis_examples.html

Vonjd
fonte
4

Usei e modifiquei o exemplo acima de Richie, funcionou como um encanto. Versão modificada para mostrar como seu modelo pode se traduzir na ingestão de dados CSV em vez de itens de texto fornecidos manualmente.

NOTA : A resposta de Richie estava faltando indicação de que 2 pacotes ( remodelar e ggplot2 ) são necessários para o / acima código abaixo ao trabalho.

rawschedule <- read.csv("sample.csv", header = TRUE) #modify the "sample.csv" to be the name of your file target. - Make sure you have headers of: Task, Start, Finish, Critical OR modify the below to reflect column count.
tasks <- c(t(rawschedule["Task"]))
dfr <- data.frame(
name        = factor(tasks, levels = tasks),
start.date  = c(rawschedule["Start"]),
end.date    = c(rawschedule["Finish"]),
is.critical = c(rawschedule["Critical"]))
mdfr <- melt(dfr, measure.vars = c("Start", "Finish"))


#generates the plot
ggplot(mdfr, aes(as.Date(value, "%m/%d/%Y"), name, colour = Critical)) + 
geom_line(size = 6) +
xlab("Duration") + ylab("Tasks") +
theme_bw()
esticado
fonte
3

Aqui está um post que escrevi sobre o uso do ggplot para gerar algo como um gráfico de Gantt. Não é muito sofisticado, mas pode lhe dar algumas idéias.

Neilfws
fonte
Obrigado, isso é realmente útil
slackline de
3

Para mim, Gvistimeline era a melhor ferramenta para fazer isso, mas sua conexão online necessária não foi útil para mim. Por isso criei um pacote chamado vistimeque usa plotly(parecido com a resposta de @Steven Beaupré), então você pode dar zoom etc .:

https://github.com/shosaco/vistime

vistime: Crie cronogramas interativos ou gráficos de Gantt usando plotly.js. Os gráficos podem ser incluídos em aplicativos Shiny e manipulados via plotly_build ().

install.packages("vistime")    
library("vistime")  

dat <- data.frame(Position=c(rep("President", 3), rep("Vice", 3)),
              Name = c("Washington", "Adams", "Jefferson", "Adams", "Jefferson", "Burr"),
              start = rep(c("1789-03-29", "1797-02-03", "1801-02-03"), 2),
              end = rep(c("1797-02-03", "1801-02-03", "1809-02-03"), 2),
              color = c('#cbb69d', '#603913', '#c69c6e'),
              fontcolor = rep("white", 3))

vistime(dat, events="Position", groups="Name", title="Presidents of the USA")

insira a descrição da imagem aqui

Shosaco
fonte
3

Pergunta muito antiga, eu sei, mas talvez valha a pena deixar aqui que - insatisfeito com as respostas que encontrei para esta pergunta - alguns meses atrás fiz um pacote básico para fazer gráficos de Gantt baseados em ggplot2 : ganttrify (mais detalhes no leia-me do pacote) .

Saída de exemplo: insira a descrição da imagem aqui

giocomai
fonte
2

A biblioteca PlotPrjNetworks fornece ferramentas de rede úteis para gerenciamento de projetos.

library(PlotPrjNetworks)
project1=data.frame(
task=c("Market Research","Concept Development","Viability Test",
"Preliminary Design","Process Design","Prototyping","Market Testing","Final Design",
"Launching"),
start=c("2015-07-05","2015-07-05","2015-08-05","2015-10-05","2015-10-05","2016-02-18",
"2016-03-18","2016-05-18","2016-07-18"),
end=c("2015-08-05","2015-08-05","2015-10-05","2016-01-05","2016-02-18","2016-03-18",
"2016-05-18","2016-07-18","2016-09-18"))
project2=data.frame(
from=c(1,2,3,4,5,6,7,8),
to=c(2,3,4,5,6,7,8,9),
type=c("SS","FS","FS","SS","FS","FS","FS","FS"),
delay=c(7,7,7,8,10,10,10,10))
GanttChart(project1,project2)

insira a descrição da imagem aqui

George Dontas
fonte
Obrigado @George por isso, há uma maneira de usar o nome das tarefas de e para? Devo postá-lo como uma nova pergunta? Com ​​base no doc github.com/cran/PlotPrjNetworks/blob/master/R/PlotPrjNetworks.R de e deve ser inteiro, existe uma solução rápida para isso?
Mohsen Sichani
1

Eu gostaria de melhorar o ggplot-Answer com várias barras para cada tarefa.

Primeiro gere alguns dados (dfrP é o data.frame da outra resposta, dfrR é algum outro data.frame com datas de realização e mdfr é um ajuste de mesclagem para a seguinte instrução ggplot () -):

library(reshape2)
tasks <- c("Review literature", "Mung data", "Stats analysis", "Write Report")
dfrP <- data.frame(
  name        = factor(tasks, levels = tasks),
  start.date  = as.Date(c("2010-08-24", "2010-10-01", "2010-11-01", "2011-02-14")),
  end.date    = as.Date(c("2010-10-31", "2010-12-14", "2011-02-28", "2011-04-30")),
  is.critical = c(TRUE, FALSE, FALSE, TRUE)
)
dfrR <- data.frame(
  name        = factor(tasks, levels = tasks),
  start.date  = as.Date(c("2010-08-22", "2010-10-10", "2010-11-01", NA)),
  end.date    = as.Date(c("2010-11-03", "2010-12-22", "2011-02-24", NA)),
  is.critical = c(TRUE, FALSE, FALSE,TRUE)
)
mdfr <- merge(data.frame(type="Plan", melt(dfrP, measure.vars = c("start.date", "end.date"))),
  data.frame(type="Real", melt(dfrR, measure.vars = c("start.date", "end.date"))), all=T)

Agora plote esses dados usando facetas para o nome da tarefa:

library(ggplot2)
ggplot(mdfr, aes(x=value, y=type, color=is.critical))+
  geom_line(size=6)+
  facet_grid(name ~ .) +
  scale_y_discrete(limits=c("Real", "Plan")) +
  xlab(NULL) + ylab(NULL)

Sem o is.critical-information, você também poderia usar Plan / Real como cor (o que eu preferiria), mas eu queria usar o data.frame da outra resposta para torná-lo melhor comparável.

Thomas Runge
fonte
1

O geom_segment encontrado no ggplot é ótimo. Das soluções anteriores, use os dados, mas não há necessidade de derreter.

library(ggplot2)

tasks <- c("Review literature", "Mung data", "Stats analysis", "Write Report")
dfr <- data.frame(
  name        = factor(tasks, levels = tasks),
  start.date  = as.Date(c("2010-08-24", "2010-10-01", "2010-11-01", "2011-02-14")),
  end.date    = as.Date(c("2010-10-31", "2010-12-14", "2011-02-28", "2011-04-30")),
  is.critical = c(TRUE, FALSE, FALSE, TRUE)
)

ggplot(dfr, aes(x =start.date, xend= end.date, y=name, yend = name, color=is.critical)) +
  geom_segment(size = 6) +
  xlab(NULL) + ylab(NULL)

GantPlot

Kbushu
fonte