在R中用ggplot2理解date和绘制直方图

主要问题

我在理解为什么处理date,标签和中断不像我在R中预期的那样尝试使用ggplot2创build直方图时遇到了问题。

我在找:

  • 我的date频率的直方图
  • 刻度标记集中在匹配条的下方
  • date标签以%Yb格式
  • 适当的限制; 最大限度地减less了网格空间的边缘和最外面的条之间的空间

我已经将我的数据上传到了pastebin ,使其具有可重现性。 我创build了几个列,因为我不确定这样做的最佳方式:

 > 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格式,所以我在这个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也改变了

我通过scale_x_date部分的ggplot2文档中的scale_x_dategeom_line()似乎在我使用相同的x轴数据时正确地打破,标记和居中geom_line() 。 我不明白为什么直方图是不同的。


更新根据从边界和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积

根据戈登的方法绘制的情节:

高登积

请注意以下几点:

  • 高登2009年12月和2010年3月阴谋的空白; table(dates$Date)显示数据中有2009-12-01 19个实例和2010-03-01 26个实例
  • 边界的情节开始于2008年4月,并于2012年5月结束。 这是基于2008年4月1日的数据中的最小值和最大date2012年5月1日的正确值。 由于某种原因,高登的阴谋始于2008年 – 3月,并且仍然在2012年5月结束。 在计算垃圾箱和阅读月份标签后,对于我的生活,我无法弄清楚哪个情节有一个额外的或缺less一个bin的直方图!

对这里的区别有什么想法? 边界的创build一个单独的计数的方法


相关参考

顺便说一句,这里有其他的地点,有路过的date和ggplot2寻找帮助的信息:

  • 在R博客learnr.wordpress 开始 。 它表示,我需要把我的数据转换成POSIXct格式,现在我认为这是错误的,浪费了我的时间。
  • 另一个学习者post在ggplot2中重新创build了一个时间序列,但并不适用于我的情况。
  • r-bloggers对此有个post ,但看起来已经过时了。 简单的format=选项不适合我。
  • 这个问题是打破和标签。 我试图把我的Date向量视为连续的,并不认为它工作得很好。 它看起来好像是一遍又一遍地覆盖相同的标签文字,所以这些字母看起来有些奇怪。 分布是正确的,但有一些奇怪的rest。 我基于接受的答案的尝试就像这样( 结果在这里 )。

UPDATE

版本2:使用Date类

我更新了这个例子来演示如何在图上alignment标签和设置限制。 我还certificate, as.Date确实在一贯使用的情况下工作(实际上它可能比我以前的示例更适合您的数据)。

目标情节v2

基于日期的直方图

守则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中做所有事情的解决scheme,在没有聚合的情况下绘制graphics,并在ggplot2 2011年底之间设置x轴上的限制。

目标情节v1

绘制在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 

当然,这可以通过玩轴上的标签选项来实现,但是这是在绘图包中用干净的短程序来完成绘图。

我认为关键是你需要在ggplot之外进行频率计算。 使用aggregate()和geom_bar(stat =“identity”)来得到没有重新sorting因子的直方图。 以下是一些示例代码:

 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) 

在题目为“基于Gauden方法的绘图”下的误差图是由于binwidth参数:… + Geom_histogram(binwidth = 30,color =“white”)+ …如果我们将30的值改为值小于20,比如10,你会得到所有的频率。

在统计数据中,数值比表示更重要,对于非常漂亮的图像来说更重要。