Подтвердить что ты не робот

Понимание дат и построение гистограммы с ggplot2 в R

Основной вопрос

У меня возникли проблемы с пониманием того, почему обработка дат, меток и перерывов не работает, как я ожидал бы в R при попытке сделать гистограмму с ggplot2.

Я ищу:

  • Гистограмма частоты моих дат
  • Отметьте метки, центрированные под соответствующими столбцами
  • метки даты в формате %Y-b
  • Соответствующие лимиты; минимизированное пустое пространство между краем сетки и внешними барами.

Я загрузил мои данные в pastebin, чтобы сделать это воспроизводимым. Я создал несколько столбцов, так как не был уверен, что это лучший способ:

> dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)
> head(dates)
       YM       Date Year Month
1 2008-Apr 2008-04-01 2008     4
2 2009-Apr 2009-04-01 2009     4
3 2009-Apr 2009-04-01 2009     4
4 2009-Apr 2009-04-01 2009     4
5 2009-Apr 2009-04-01 2009     4
6 2009-Apr 2009-04-01 2009     4

Вот что я пробовал:

library(ggplot2)
library(scales)
dates$converted <- as.Date(dates$Date, format="%Y-%m-%d")

ggplot(dates, aes(x=converted)) + geom_histogram()
+      opts(axis.text.x = theme_text(angle=90))

Что дает этот график. Я хотел форматировать %Y-%b, тем не менее, поэтому я охотился и пробовал следующее, основанное на this SO:

ggplot(dates, aes(x=converted)) + geom_histogram()
+    scale_x_date(labels=date_format("%Y-%b"),
+    breaks = "1 month")
+    opts(axis.text.x = theme_text(angle=90))

stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.

Это дает мне этот график

  • Правильный формат метки оси x
  • Частотное распределение изменило форму (проблема с пропускной способностью?)
  • Отметки меток не отображаются по центру
  • Изменены также xlims

Я работал над примером в документации ggplot2 в разделе scale_x_date и geom_line(), как представляется, разбился, был отмечен ярлыком и центром тикает правильно, когда я использую его с теми же данными оси x. Я не понимаю, почему гистограмма отличается.


Обновления, основанные на ответах от edgeter и gauden

Первоначально я думал, что ответ gauden помог мне решить мою проблему, но теперь я озадачен, посмотрев более внимательно. Обратите внимание на различия между результирующими графами ответов после кода.

Предположим, что для:

library(ggplot2)
library(scales)
dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)

Основываясь на ответе @edgester ниже, я смог сделать следующее:

freqs <- aggregate(dates$Date, by=list(dates$Date), FUN=length)
freqs$names <- as.Date(freqs$Group.1, format="%Y-%m-%d")

ggplot(freqs, aes(x=names, y=x)) + geom_bar(stat="identity") +
       scale_x_date(breaks="1 month", labels=date_format("%Y-%b"),
                    limits=c(as.Date("2008-04-30"),as.Date("2012-04-01"))) +
       ylab("Frequency") + xlab("Year and Month") +
       theme_bw() + opts(axis.text.x = theme_text(angle=90))

Вот моя попытка, основанная на ответе gauden:

dates$Date <- as.Date(dates$Date)
ggplot(dates, aes(x=Date)) + geom_histogram(binwidth=30, colour="white") +
       scale_x_date(labels = date_format("%Y-%b"),
                    breaks = seq(min(dates$Date)-5, max(dates$Date)+5, 30),
                    limits = c(as.Date("2008-05-01"), as.Date("2012-04-01"))) +
       ylab("Frequency") + xlab("Year and Month") +
       theme_bw() + opts(axis.text.x = theme_text(angle=90))

Участок, основанный на приближении кромки:

edgester-plot

Участок, основанный на методе gauden:

gauden-plot

Обратите внимание на следующее:

  • пробелы в гауденском заговоре за 2009 год-декабрь и 2010-Мар; table(dates$Date) показывает, что имеется 19 экземпляров 2009-12-01 и 26 экземпляров 2010-03-01 в данных График
  • начинается с 2008-Апр и заканчивается в 2012-мае. Это верно на основе минимального значения в данных за 2008-04-01 и максимальной даты 2012-05-01. По какой-то причине гауденский сюжет начинается в 2008-Мар и все еще каким-то образом заканчивается в 2012-мае. После подсчета ящиков и чтения по меткам месяца, для жизни я не могу понять, какой сюжет имеет дополнительный или отсутствует бин гистограммы!

Любые мысли о различиях здесь? рестрикционный метод создания отдельного счета


Ссылки по теме

В стороне, вот другие местоположения, которые имеют информацию о датах и ​​ggplot2 для прохожих, ищут помощь:

4b9b3361

Ответ 1

UPDATE

Версия 2: Использование класса Date

Я обновляю пример, чтобы продемонстрировать выравнивание меток и установление ограничений на графике. Я также демонстрирую, что as.Date действительно работает, когда используется последовательно (на самом деле это, вероятно, лучше подходит для ваших данных, чем мой предыдущий пример).

Целевой план v2

date-based histogram

Код v2

И вот (несколько чрезмерно) прокомментированный код:

library("ggplot2")
library("scales")

dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)
dates$Date <- as.Date(dates$Date)

# convert the Date to its numeric equivalent
# Note that Dates are stored as number of days internally,
# hence it is easy to convert back and forth mentally
dates$num <- as.numeric(dates$Date)

bin <- 60 # used for aggregating the data and aligning the labels

p <- ggplot(dates, aes(num, ..count..))
p <- p + geom_histogram(binwidth = bin, colour="white")

# The numeric data is treated as a date,
# breaks are set to an interval equal to the binwidth,
# and a set of labels is generated and adjusted in order to align with bars
p <- p + scale_x_date(breaks = seq(min(dates$num)-20, # change -20 term to taste
                                   max(dates$num), 
                                   bin),
                      labels = date_format("%Y-%b"),
                      limits = c(as.Date("2009-01-01"), 
                                 as.Date("2011-12-01")))

# from here, format at ease
p <- p + theme_bw() + xlab(NULL) + opts(axis.text.x  = theme_text(angle=45,
                                                                  hjust = 1,
                                                                  vjust = 1))
p

Версия 1: Использование POSIXct

Я пробую решение, которое делает все в ggplot2, рисует без агрегации и устанавливает пределы по оси x в начале 2009 года и в конце 2011 года.

Целевой график v1

plot with limits set in ggplot2

Код v1

library("ggplot2")
library("scales")

dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)
dates$Date <- as.POSIXct(dates$Date)

p <- ggplot(dates, aes(Date, ..count..)) + 
    geom_histogram() +
    theme_bw() + xlab(NULL) +
    scale_x_datetime(breaks = date_breaks("3 months"),
                     labels = date_format("%Y-%b"),
                     limits = c(as.POSIXct("2009-01-01"), 
                                as.POSIXct("2011-12-01")) )

p

Конечно, это может быть связано с игрой с опциями метки на оси, но это должно округлить график с чистой короткой процедурой в пакете печати. ​​

Ответ 2

Я думаю, что главное, что вам нужно делать вычисление частоты вне ggplot. Используйте aggregate() с geom_bar (stat = "identity" ), чтобы получить гистограмму без переупорядоченных факторов. Вот пример кода:

require(ggplot2)

# scales goes with ggplot and adds the needed scale* functions
require(scales)

# need the month() function for the extra plot
require(lubridate)

# original data
#df<-read.csv("http://pastebin.com/download.php?i=sDzXKFxJ", header=TRUE)

# simulated data
years=sample(seq(2008,2012),681,replace=TRUE,prob=c(0.0176211453744493,0.302496328928047,0.323054331864905,0.237885462555066,0.118942731277533))
months=sample(seq(1,12),681,replace=TRUE)
my.dates=as.Date(paste(years,months,01,sep="-"))
df=data.frame(YM=strftime(my.dates, format="%Y-%b"),Date=my.dates,Year=years,Month=months)
# end simulated data creation

# sort the list just to make it pretty. It makes no difference in the final results
df=df[do.call(order, df[c("Date")]), ]

# add a dummy column for clarity in processing
df$Count=1

# compute the frequencies ourselves
freqs=aggregate(Count ~ Year + Month, data=df, FUN=length)

# rebuild the Date column so that ggplot works
freqs$Date=as.Date(paste(freqs$Year,freqs$Month,"01",sep="-"))

# I set the breaks for 2 months to reduce clutter
g<-ggplot(data=freqs,aes(x=Date,y=Count))+ geom_bar(stat="identity") + scale_x_date(labels=date_format("%Y-%b"),breaks="2 months") + theme_bw() + opts(axis.text.x = theme_text(angle=90))
print(g)

# don't overwrite the previous graph
dev.new()

# just for grins, here is a faceted view by year
# Add the Month.name factor to have things work. month() keeps the factor levels in order
freqs$Month.name=month(freqs$Date,label=TRUE, abbr=TRUE)
g2<-ggplot(data=freqs,aes(x=Month.name,y=Count))+ geom_bar(stat="identity") + facet_grid(Year~.) + theme_bw()
print(g2)

Ответ 3

График ошибок под заголовком "Участок, основанный на подходе Гаудена", обусловлен параметром бинарной ширины: ... + Geom_histogram (binwidth = 30, color = "white" ) +... Если мы изменим значение 30 на значение меньше 20, например 10, вы получите все частоты.

В статистике значения важнее, чем презентация, более важная для мягкой графики для очень красивой картинки, но с ошибками.