R Create function to add water year column

前端 未结 2 660
被撕碎了的回忆
被撕碎了的回忆 2020-12-17 06:09

I want to be able to create a water year column for a time series. The US water year is from Oct-Sept and is considered the year it ends on. For example the 2014 water yea

相关标签:
2条回答
  • 2020-12-17 06:29

    I had a similar problem a while back but dealing with fiscal years that started in October. I found this function which also computes the quarters within the year. For one part, I only wanted it to output the fiscal year, so I edited a tiny part of the function to do that. There is surely a much cleaner/efficient way of doing it, but this should work for smaller data sets. Here is the edited 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))
    } 
    

    Your input vector should be type Date, and then specify the start month. Assuming you have a data frame(df) with the 'date' column as in your question, this should do the trick.

    df$wtr_yr <- getYearQuarter(df$date, firstMonth=10)
    
    0 讨论(0)
  • 2020-12-17 06:47

    We can use POSIXlt to come up with an answer.

    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
    }
    

    Let's now use this function in an example.

    # 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))
    
    0 讨论(0)
提交回复
热议问题