R创建添加水年列的功能

时间:2014-12-23 19:08:58

标签: r date datetime time-series

我希望能够为时间序列创建水年专栏。美国水年是从10月到9月,被认为是结束的一年。例如,2014年的水年是2013年10月1日至2014年9月30日。

这是美国的水年,但不是唯一的水年。因此,我想在开始月份输入,并计算该日期的水年。

例如,如果我的数据看起来像

        date
2008-01-01 00:00:00
2008-02-01 00:00:00
2008-03-01 00:00:00
2008-04-01 00:00:00
       .
       .
       .
2008-12-01 00:00:00

我希望我的功能能够像:

wtr_yr <- function(data, start_month) {

does stuff

}

然后我的输出将是

wtr_yr(data, 2)

         date                    wtr_yr
    2008-01-01 00:00:00           2008
    2008-02-01 00:00:00           2009 
    2008-03-01 00:00:00           2009
    2008-04-01 00:00:00           2009
           .
           .
           .
    2009-01-01 00:00:00           2009 
    2009-02-01 00:00:00           2010
    2009-03-01 00:00:00           2010
    2009-04-01 00:00:00           2010

我开始将日期分成不同的列,但我不认为这是最好的方法。有什么建议?

提前致谢!

2 个答案:

答案 0 :(得分:5)

我们可以使用POSIXlt来提出答案。

wtr_yr <- function(dates, start_month=9) {
  # Convert dates into POSIXlt
  dates.posix = as.POSIXlt(dates)
  # Year offset
  offset = ifelse(dates.posix$mon >= start_month - 1, 1, 0)
  # Water year
  adj.year = dates.posix$year + 1900 + offset
  # Return the water year
  adj.year
}

现在让我们在一个例子中使用这个功能。

# Sample input vector
dates = c("2008-01-01 00:00:00",
"2008-02-01 00:00:00",
"2008-03-01 00:00:00",
"2008-04-01 00:00:00",
"2009-01-01 00:00:00",
"2009-02-01 00:00:00",
"2009-03-01 00:00:00",
"2009-04-01 00:00:00")

# Display the function output
wtr_yr(dates, 2)

# Combine the input and output vectors in a dataframe
df = data.frame(dates, wtr_yr=wtr_yr(dates, 2))

答案 1 :(得分:1)

我有一段时间遇到过类似的问题但处理了10月开始的财政年度。我发现this function也计算了一年内的季度。对于一部分,我只希望它输出会计年度,所以我编辑了一小部分功能来做到这一点。肯定有一种更清洁/有效的方法,但这应该适用于较小的数据集。这是编辑过的功能:

getYearQuarter <- function(x,
        firstMonth=7,
        fy.prefix='FY',
        quarter.prefix='Q',
        sep='-',
        level.range=c(min(x), max(x)) ) {
if(level.range[1] > min(x) | level.range[2] < max(x)) {
        warning(paste0('The range of x is greater than level.range. Values ',
            'outside level.range will be returned as NA.'))
}
quarterString <- function(d) {
        year <- as.integer(format(d, format='%Y'))
        month <- as.integer(format(d, format='%m'))
        y <- ifelse(firstMonth > 1 & month >= firstMonth, year+1, year)
        q <- cut( (month - firstMonth) %% 12, breaks=c(-Inf,2,5,8,Inf),
            labels=paste0(quarter.prefix, 1:4))
        return(paste0(fy.prefix, substring(y,3,4)))
}
vals <- quarterString(x)
levels <- unique(quarterString(seq(
        as.Date(format(level.range[1], '%Y-%m-01')),
        as.Date(format(level.range[2], '%Y-%m-28')), by='month')))
return(factor(vals, levels=levels, ordered=TRUE))
} 

您的输入向量应为 Date ,然后指定开始月份。假设您有一个带有&#39;日期&#39;的数据框(df)。如你的问题所示,这应该可以解决问题。

df$wtr_yr <- getYearQuarter(df$date, firstMonth=10)