理解日期并在R中用ggplot2绘制直方图

主要问题

我在理解为什么处理日期,标签和中断时不能正常工作,因为我试图用ggplot2创建直方图时,会出现R中预期的问题。

我在找:

  • 我日期频率的直方图
  • 勾号标记集中在匹配条的下方
  • 日期标签以%Yb格式显示
  • 适当的限制; 最大限度地减少网格空间边缘与最外面的条之间的空间
  • 我已将我的数据上传到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格式化,所以我在这个基础上寻找并尝试了以下内容:

    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轴标签格式
  • 频率分布改变了形状(binwidth问题?)
  • 刻度线不会出现在小节下方
  • 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日的数据中的最小值和2012-05-01的最大日期,这是正确的。 由于某种原因,戈登的情节开始于2008年3月,并且仍然以某种方式在2012年5月结束。 在计算垃圾箱和阅读月份标签后,对于我的生活,我无法弄清楚哪个图有额外的或缺少直方图的bin!
  • 对这里的区别有什么想法? 边界的创建一个单独的计数的方法


    相关参考

    顺便说一下,以下是其他位置,其中包含有关日期和ggplot2的路人寻找帮助的信息:

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

  • UPDATE

    版本2:使用Date类

    我更新了示例以演示对齐图上的标签和设置限制。 我还证明, 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中的所有ggplot2 ,绘制没有聚合的图形,并在2009年年初至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”)来获得没有重新排序的因子的直方图。 以下是一些示例代码:

    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的值更改为a值小于20,比如10,你会得到所有的频率。

    在统计数据中,这些值比表示更重要,对于非常漂亮的图像来说更重要的是平淡的图形,但是有错误。

    链接地址: http://www.djcxy.com/p/24927.html

    上一篇: Understanding dates and plotting a histogram with ggplot2 in R

    下一篇: Acquiring basic skills working with visualizing/analyzing large data sets