【问题标题】:R + ggplot2: how to hide missing dates from x-axis?R + ggplot2:如何从 x 轴隐藏缺失的日期?
【发布时间】:2011-03-02 15:03:34
【问题描述】:

假设我们有以下简单的日期值对数据框,其中序列中缺少一些日期(即 1 月 12 日至 1 月 14 日)。当我绘制这些点时,它会在 x 轴上显示这些缺失的日期,但没有对应于这些日期的点。我想防止这些缺失的日期出现在 x 轴上,以便点序列没有中断。关于如何做到这一点的任何建议?谢谢!

dts <- c(as.Date( c('2011-01-10', '2011-01-11', '2011-01-15', '2011-01-16')))
df <- data.frame(dt = dts, val = seq_along(dts)) 
ggplot(df, aes(dt,val)) + geom_point() + 
        scale_x_date(format = '%d%b', major='days')

【问题讨论】:

    标签: r plot ggplot2


    【解决方案1】:

    我做了一个 package 来做到这一点。它被称为bdscale,位于CRAN 和github。无耻的插头。

    复制你的例子:

    > library(bdscale)
    > library(ggplot2)
    > library(scales)
    > dts <- as.Date( c('2011-01-10', '2011-01-11', '2011-01-15', '2011-01-16'))
    > ggplot(df, aes(x=dt, y=val)) + geom_point() + 
        scale_x_bd(business.dates=dts, labels=date_format('%d%b'))
    

    但您可能想要的是加载已知的有效日期,然后使用 x 轴上的有效日期绘制数据:

    > nyse <- bdscale::yahoo('SPY') # get valid dates from SPY prices
    > dts <- as.Date('2011-01-10') + 1:10
    > df <- data.frame(dt=dts, val=seq_along(dts))
    > ggplot(df, aes(x=dt, y=val)) + geom_point() + 
        scale_x_bd(business.dates=nyse, labels=date_format('%d%b'), max.major.breaks=10)
    
    Warning message:
    Removed 3 rows containing missing values (geom_point). 
    

    警告告诉您它删除了三个日期:

    • 15th = 星期六
    • 16 日 = 周日
    • 17 日 = MLK 日

    【讨论】:

    • 稍微更正一下,您创建了一个执行此操作的 包(不是库)
    • 我为你准备了一个包裹就在这里,伙计。哎呀。但你是对的先生,我会修改的。
    【解决方案2】:

    然后将日期数据转换为因子。目前,ggplot 正在按照您告诉它数据所在的意义上解释数据 - 一个连续的日期刻度。你不想要那个尺度,你想要一个分类尺度:

    require(ggplot2)
    dts <- as.Date( c('2011-01-10', '2011-01-11', '2011-01-15', '2011-01-16'))
    df <- data.frame(dt = dts, val = seq_along(dts)) 
    ggplot(df, aes(dt,val)) + geom_point() + 
            scale_x_date(format = '%d%b', major='days')
    

    对

    df <- data.frame(dt = factor(format(dts, format = '%d%b')), 
                      val = seq_along(dts)) 
    ggplot(df, aes(dt,val)) + geom_point()
    

    产生:

    这是你想要的吗?

    【讨论】:

    • @Gavin,谢谢......但这改变了显示的日期:我有 10 月 10 日至 16 日,现在我们得到 2 月 2 日至 5 月。有什么办法可以解决吗?我想我可以将日期视为字符串,并完全失去日期语义,但有没有办法不失去日期语义?
    • 但这些是连续日期,而不是原始问题中的日期。
    • 我注意到了,忘记按照原始比例格式化日期。我的错 - 现在查看答案。
    • @Joris 谢谢 - 你为什么删除你的答案?它包含了我的回答中没有的一些优点,例如某些日期格式的排序等。我正要对其进行投票,但在我回答另一条评论时它已经消失了
    • 订购是个好主意。一旦您遇到不同的月份、一位数与两位数的日子,您可能想要ordered() 而不是factor()(或适当的ordered=TRUE 标志)...
    【解决方案3】:

    第一个问题是:你为什么要这样做?如果您的轴不是坐标,则显示基于坐标的图是没有意义的。如果你真的想这样做,你可以转换为一个因子。不过请注意订单:

    dts <- c(as.Date( c('31-10-2011', '01-11-2011', '02-11-2011',
               '05-11-2011'),format="%d-%m-%Y"))
    dtsf <- format(dts, format= '%d%b')
    df <- data.frame(dt=ordered(dtsf,levels=dtsf),val=seq_along(dts))
    ggplot(df, aes(dt,val)) + geom_point()
    

    对于因子,您必须小心,因为因子中的顺序是任意的,除非您将其设为有序因子。由于因子默认按字母顺序排列,因此您可能会遇到一些日期格式的问题。所以要小心你做什么。如果您不考虑订单,您会得到:

    df <- data.frame(dt=factor(dtsf),val=seq_along(dts))
    ggplot(df, aes(dt,val)) + geom_point()
    

    【讨论】:

    • 在金融时间序列中,周末没有数据是很常见的,因此在有周末的地块中进行休息在视觉上并不好。
    • @Prasad:我明白了。我宁愿在 X 轴上添加诸如“工作日”之类的内容,因为现在您给人的印象是连续函数实际上在 X 轴上不连续。听起来像是在吹毛求疵,但它可能会让人很困惑。
    • @JorisMeys 如果有重复时间怎么办?
    猜你喜欢
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    相关资源
    最近更新 更多