【问题标题】:How to find decimal representation of years in R?如何在R中找到年份的十进制表示?
【发布时间】:2016-04-10 09:16:19
【问题描述】:

由于我需要以十进制格式合理准确地表示年份(~4-5 位 的精度可以),所以我转向了 lubridate 包。这是我尝试过的:

refDate <- as.Date("2016-01-10")
endDate <- as.Date("2020-12-31")
daysInLeapYear <- 366
daysInRegYear <- 365
leapYearFractStart <- 0
leapYearRegStart <- 0
daysInterval <- as.interval(difftime(endDate, refDate, unit = "d"), start = refDate)
periodObject <- as.period(daysInterval)
if(leap_year(refDate)) {
    leapYearFractStart <- (as.numeric(days_in_month(refDate))-as.numeric(format(refDate, "%d")))/daysInLeapYear
}
if(!leap_year(refDate)) {
    leapYearRegStart <- (as.numeric(days_in_month(refDate))-as.numeric(format(refDate, "%d")))/daysInRegYear
}
returnData <- periodObject@year+(periodObject@month/12)+leapYearFractStart+leapYearRegStart

可以安全地假设结束日期总是在月底,因此最后没有闰年检查。依靠 lubridate 进行正确的年/月计数,我仅针对开始日期调整闰年。

我发现这让我的准确度只有 3 位数!另外,它看起来有点粗糙。

是否有更完整、更准确的程序来确定区间内年份的十进制表示?

【问题讨论】:

    标签: r date time lubridate


    【解决方案1】:

    目前还不清楚您究竟想在这里做什么,这使得准确性难以谈论。

    lubridate 有一个函数decimal_date 可以将日期转换为小数。但是由于 3 位小数在一年内为您提供了 1000 个可能的位置,当我们只有 365/366 天时,一天内就有 2 到 3 个可行的值。准确性取决于您希望结果下降的时间。

    > decimal_date(as.POSIXlt("2016-01-10 00:00:01"))
    [1] 2016.025
    > decimal_date(as.POSIXlt("2016-01-10 12:00:00"))
    [1] 2016.026
    > decimal_date(as.POSIXlt("2016-01-10 23:59:59"))
    [1] 2016.027
    

    换句话说,只有当您对一天中的时间感兴趣时,超过小数点后 3 位才真正重要。

    【讨论】:

    • 感谢 decimal_date() 正是我需要的,不知道它在那里。很好的答案,谢谢!事实上,我对一天中的时间很感兴趣。
    【解决方案2】:

    此解决方案仅使用基数 R。我们使用 cut(..., "year") 获得年初,并通过将其与使用 cut(..., "year") 在下一年。最后使用这些数量来获得分数并将其添加到年份。

    d <- as.Date(c("2015-01-31", "2016-01-01", "2016-01-10", "2016-12-31")) # sample input
    
    year_begin <- as.Date(cut(d, "year"))
    days_in_year <- as.numeric( as.Date(cut(year_begin + 366, "year")) - year_begin )
    as.numeric(format(d, "%Y")) + as.numeric(d - year_begin) / days_in_year
    ## [1] 2015.082 2016.000 2016.025 2016.997
    

    或者,使用as.POSIXlt 这个变体将它塞进一行:

    with(unclass(as.POSIXlt(d)),1900+year+yday/as.numeric(as.Date(cut(d-yday+366,"y"))-d+yday))
    ## [1] 2015.082 2016.000 2016.025 2016.997
    

    【讨论】:

      猜你喜欢
      • 2021-06-23
      • 2021-12-26
      • 2016-05-23
      • 2015-11-10
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多