График временной шкалы в стиле Ганта (в базе R) - PullRequest
12 голосов
/ 25 марта 2012

У меня есть датафрейм, который выглядит так:

       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

Где начало и конец - это время или продолжительность (sam говорил от 0 до 6; greg от 6 до 11 и т. Д.). n - как долго (в данном случае # слов) человек говорил. Я хочу представить это как временную шкалу в базе R (в конечном итоге я могу задать аналогичный вопрос, используя ggplot2, но этот ответ специфичен для базы R [когда я говорю «база», я имею в виду пакеты, которые поставляются со стандартной установкой]).

Ось у будет человеком, а ось х будет временем. Надеемся, что конечный продукт будет выглядеть примерно так по приведенным выше данным:

Timeline_Graph

Я хотел бы использовать базу R, чтобы сделать это. Я не уверен, как подойти к этому. Мои мысли - использовать точечный график и построить точечный график, но не использовать точки. Тогда идите через это с квадратными сегментами конца. Я не уверен в том, как это будет работать, поскольку сегментам нужны числовые точки x и y, чтобы сделать сегменты, а ось y является категориальной. Другая идея состоит в том, чтобы преобразовать коэффициенты в числовые (назначить каждому фактору число) и построить в виде пустой диаграммы рассеяния, а затем перейти к квадратным отрезкам конечных линий. Это может быть мощным инструментом в моей области, глядя на образцы речи.

Заранее благодарю за помощь.

PS аргумент для сегментов линии с квадратным концом - segments(... , lend=2) , чтобы сэкономить время на поиск этой информации для тех, кто не знаком со всеми аргументами сегмента.

Ответы [ 3 ]

29 голосов
/ 25 марта 2012

Вы говорите, что хотите решение Base R, но не говорите почему.Так как это одна строка кода в ggplot, я все равно это покажу.

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

enter image description here

16 голосов
/ 25 марта 2012

Очень похоже на подход @ Джона, но так как я это сделал, я опубликую его:)

Вот общая функция для построения диаграммы Ганта (без зависимостей):

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'))

Результат:

enter image description here

8 голосов
/ 25 марта 2012

Пока ось Y является категориальной, все, что вам нужно сделать, это присвоить номера категориям (1: 5) и отслеживать их. Использование по умолчанию as.numeric () фактора обычно нумерует их в алфавитном порядке, но вы все равно должны это проверить. Создайте свой график с аргументом xaxt = 'n'. Затем используйте команду axis (), чтобы вставить ось Y.

axis(2, 1:5, myLabels)

Имейте в виду, что всякий раз, когда вы планируете рисовать, единственный способ разместить вещи - это число. Категориальными значениями x или y всегда являются только числа 1: nКатегории с метками названий категорий вместо чисел на оси.

Что-то вроде следующего достаточно близко (если ваш объект 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...