了解日期并在R中使用ggplot2绘制直方图 主要问题

了解日期并在R中使用ggplot2绘制直方图 主要问题,r,datetime,ggplot2,histogram,R,Datetime,Ggplot2,Histogram,当我试图用ggplot2制作柱状图时,我在理解为什么日期、标签和中断的处理不像我在R中预期的那样有效时遇到了问题 我在找: 我约会频率的柱状图 在匹配条下居中的记号 日期标签采用%Y-b格式 适当的限制;最小化网格空间边缘和最外层条之间的空白空间 我必须让它重现。我已经创建了几个专栏,因为我不确定这样做的最佳方式: > dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T) &g

当我试图用ggplot2制作柱状图时,我在理解为什么日期、标签和中断的处理不像我在R中预期的那样有效时遇到了问题

我在找:

  • 我约会频率的柱状图
  • 在匹配条下居中的记号
  • 日期标签采用
    %Y-b
    格式
  • 适当的限制;最小化网格空间边缘和最外层条之间的空白空间
我必须让它重现。我已经创建了几个专栏,因为我不确定这样做的最佳方式:

> 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
这给了我

  • 正确的x轴标签格式
  • 频率分布已改变形状(宽度问题?)
  • 勾号不会显示在条形下方的中心位置
  • XLIM也发生了变化
我在
scale\u x\u date
部分中完成了示例,当我使用相同的x轴数据时,
geom\u line()
显示为正确断开、标记和居中刻度。我不明白为什么柱状图不同


根据edgester和gauden的回答进行更新 起初我以为高登的回答帮助我解决了问题,但现在仔细观察后我感到困惑。注意代码后面两个答案的结果图之间的差异

假设两者都是:

library(ggplot2)
library(scales)
dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)
库(ggplot2)
图书馆(比例尺)

日期我认为关键是你需要在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)
require(ggplot2)
#scales与ggplot一起使用,并添加所需的scale*函数
需要(天平)
#需要用于额外绘图的month()函数
要求(润滑)
#原始数据

#df更新

版本2:使用日期类 我更新了示例以演示对齐标签和设置绘图限制。我还演示了当一致使用时,
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

当然,这可能与在轴上玩标签选项有关,但这是在绘图软件包中使用干净的短例程来完成绘图。

标题“基于Gauden方法的绘图”下的错误图是由binwidth参数引起的: ... + 几何图形直方图(binwidth=30,color=“white”)+。。。 如果我们将值30更改为小于20的值,例如10,您将获得所有频率


在统计学中,值比表示更重要。对于一幅非常漂亮但有错误的图片来说,平淡的图形更重要。

我知道这是一个老问题,但对于2021年(或以后)的任何人来说,使用
breaks=
参数
geom\u histogram()
并创建一个小快捷功能,以生成所需的序列

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

dates$Date <- lubridate::ymd(dates$Date)

by_month <- function(x,n=1){
  seq(min(x,na.rm=T),max(x,na.rm=T),by=paste0(n," months"))
}

ggplot(dates,aes(Date)) +
  geom_histogram(breaks = by_month(dates$Date)) +
  scale_x_date(labels = scales::date_format("%Y-%b"),
               breaks = by_month(dates$Date,2)) + 
  theme(axis.text.x = element_text(angle=90))

dates查看
lubridate
软件包。@gsk3我听说过,但我的理解是它有助于格式化、间隔、递增等等。你认为我的问题在于润滑油会有帮助吗?我想应该是正确使用ggplot2的语法。我不明白你的问题。你有没有试着问一个问题,然后在同一篇文章中回答?如果是这样,请将你的问题改为一个问题,然后自己回答。(这是积极鼓励的。)请提出一个新问题,因为您刚刚从原始数据集切换了数据集。这个问题读起来很混乱。请接受一个答案,并对任何有帮助的答案进行投票。@edgester:我可以重新写这个问题。很难保持简洁。问题是ggplot2与日期/时间混淆。我想说明有多少种理论方法可以使这项工作发挥作用,以及每种方法都存在的问题。我计划解决这个问题。。。但是,仅仅使用我已经提供的数据似乎会容易得多。你为什么不这么做?它同时具有一组本应可以使用的值,即
%Y-%b
%Y-%m-%d
?请参阅问题中的更新部分。我可以应用你对聚合的使用来做我想做的事情。看一看,;我想你不需要你的
df$Count
vector或者你做的其他事情来得到一个有用的结果。现在我只想知道如何根据日期范围设置限制。我也不需要lubridate,我为后代提供了虚拟数据。当pastebin条目消失时,StackOverflow问题可能仍然存在。在这种情况下,我的答案仍然有效。您是对的,lubridate只用于第二个图形,而不是第一个图形。您没有在pastebin中更改数据,但在R代码中添加了alter。您添加了“Price”变量,这不在原始问题中。你已经改变了你的问题,最好是开始一个新的问题。整个问题现在很难理解。啊。是的,我做到了。但请注意我为什么这么做。我清楚地引用了ggplot2文档,其中包含确切的变量用法。我只是想生成另一个变量,这样我就可以绘制直方图以外的东西。然后我展示了使用geom_line()可以生成所需的x轴和比例,而直方图则不能。我肯定会考虑拆分这一点——我应该问一个关于线和直方图图之间的Suxexx日期处理的具体问题吗?谢谢。一些问题。1) 即使在阅读了文档之后,我也不理解date和datetime之间的区别。2) 为什么as.POSIXct向量可以工作,而as.Date不能?3) 同样,为什么不使用
c(如.D)设置限制
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))
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)
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
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
dates <- read.csv("http://pastebin.com/raw.php?i=sDzXKFxJ", sep=",", header=T)

dates$Date <- lubridate::ymd(dates$Date)

by_month <- function(x,n=1){
  seq(min(x,na.rm=T),max(x,na.rm=T),by=paste0(n," months"))
}

ggplot(dates,aes(Date)) +
  geom_histogram(breaks = by_month(dates$Date)) +
  scale_x_date(labels = scales::date_format("%Y-%b"),
               breaks = by_month(dates$Date,2)) + 
  theme(axis.text.x = element_text(angle=90))