Штабелированный столбчатый график в R с несколькими рядами в день
Я хотел бы отобразить работу, выполненную за день, в виде сложенной линейчатой диаграммы, чтобы увидеть, День за днем, сколько действий я сделал в каждой категории, с осью Y, представляющей время от 0:00 до 23:59.
# day tstart tend duration category
1 2012-10-01 13:40 14:16 36 Recreation
2 2012-10-02 10:15 10:57 42 Work
3 2012-10-02 13:23 13:47 24 Chores
4 2012-10-02 13:47 14:48 61 Work
5 2012-10-03 09:09 11:40 151 Work
6 2012-10-03 13:33 14:04 31 Recreation
7 2012-10-03 17:00 19:40 160 Recreation
Я знаю, что мне придется преобразовать "время начала" в числовое значение, но я не знаю, как "объединить" несколько строк для одного и того же дня, чтобы они составляли только один бар в графике.
В (очень примитивном) ASCII-искусстве я ожидаю чего-то например:
23:00
22:00
21:00
20:00
19:00 C
18:00 C
17:00 C
16:00
15:00
14:00 W R
13:00 R C
12:00
11:00 W
10:00 W W
9:00 W
8:00
7:00
6:00
5:00
4:00
3:00
2:00
1:00
0:00
01 02 03
(где R, W и C были бы полосами разного цвета для различных видов деятельности: отдыха, работы и домашних дел)
На самом деле, будучи новичком в R plots, я не знаю функцию plot (и пакет plot), на которую я должен смотреть, более того, поскольку они будут дырами в графике-никакой активности не зарегистрировано (например) между 0:00 и 09:09, затем между 11:40 и 13:33 и т. д. на 2012-10-03...
2 ответа:
Вот быстрое решение с
ggplot2
:d <- read.table(textConnection(" day tstart tend duration category 2012-10-01 13:40 14:16 36 Recreation 2012-10-02 10:15 10:57 42 Work 2012-10-02 13:23 13:47 24 Chores 2012-10-02 13:47 14:48 61 Work 2012-10-03 09:09 11:40 151 Work 2012-10-03 13:33 14:04 31 Recreation 2012-10-03 17:00 19:40 160 Recreation"), header=TRUE) d$day <- as.Date(d$day) d$tstart <- as.POSIXct(d$tstart, format="%H:%M") d$tend <- as.POSIXct(d$tend, format="%H:%M") library(ggplot2) library(scales) g <- ggplot(data=d, aes()) + geom_segment(aes(x=day,xend=day,y=tstart,yend=tend,color=category),size=20) + scale_x_date(labels = date_format("%d")) g + scale_y_datetime(limits=c(as.POSIXct("00:00", format="%H:%M"),as.POSIXct("23:59", format="%H:%M")), labels = date_format("%H:%M"))
Что дает :
Отредактировано: ось y в первоначальном ответе была неправильной.
Пока я писал этот пост, Дзюба опубликовал отличное решение, используя ggplot2, я тем не менее опубликую свое решение в качестве альтернативы.
Это очень грубый способ сделать это, но он выполняет то, что вы, возможно, ищете.Сначала небольшая функция полезности для преобразования времени формата
hh:mm
в десятичное представлениеdecTime <- function(x) { t <- as.numeric(strsplit(x, ":")[[1]]) t <- t[1] + t[2]/60 return(t) } str <- 'n day tstart tend duration category 1 2012-10-01 13:40 14:16 36 Recreation 2 2012-10-02 10:15 10:57 42 Work 3 2012-10-02 13:23 13:47 24 Chores 4 2012-10-02 13:47 14:48 61 Work 5 2012-10-03 09:09 11:40 151 Work 6 2012-10-03 13:33 14:04 31 Recreation 7 2012-10-03 17:00 19:40 160 Recreation' df <- read.table(textConnection(str), header=T)
Преобразовать день в число (для удобства указания ширины прямоугольников) и время в десятичное
df$day <- gsub('2012-10-', "", df$day) df$day <- as.numeric(df$day) df$starttime <- sapply(as.character(df$tstart), decTime, USE.NAMES=F) df$endtime <- sapply(as.character(df$tend), decTime, USE.NAMES=F)
Получить цвета для различных прямоугольники
df$color <- ifelse(df$category=='Recreation', 'RED', ifelse(df$category =='Chores', 'BLUE', 'GREEN'))
Постройте график шаг за шагом
#Plot empty graph plot(x=unique(df$day), y=c(0,0,0), axes=F, ylim=c(0,24), xlim=c(0.5,3.5), xlab='date', ylab='time', type='n') #Label axes properly axis(side=1, at=c(1,2,3), labels=c('01', '02', '03')) axis(side=2, at=seq(from=0,to=24,by=1), labels=seq(from=0,to=24,by=1)) #Draw required rectangles rect(df$day-0.25, df$starttime, df$day+0.25, df$endtime, col=df$color)
Результат должен быть таким, как вы хотите.