使用R中的POSIXlt向X添加一个月的问题 - 需要使用as.Date(X)重置值

时间:2013-02-12 22:58:01

标签: r datetime posixct

这适用于R:

# Setting up the first inner while-loop controller, the start of the next water year
  NextH2OYear <- as.POSIXlt(firstDate)
  NextH2OYear$year <- NextH2OYear$year + 1
  NextH2OYear<-as.Date(NextH2OYear)

但这不是:

# Setting up the first inner while-loop controller, the start of the next water month
  NextH2OMonth <- as.POSIXlt(firstDate)
  NextH2OMonth$mon <- NextH2OMonth$mon + 1
  NextH2OMonth <- as.Date(NextH2OMonth)

我收到此错误:

as.Date.POSIXlt(NextH2OMonth)出错:   非空POSIXlt结构中的零长度组件

任何想法为什么?我需要系统地添加一年(一个循环)和一个月(另一个循环)并将结果更改的变量与一个Date类的值进行比较,这就是使用as.Date()将它们转换回来的原因。

谢谢, 汤姆

编辑:

以下是整段代码。我正在使用RStudio(版本0.97.306)。下面的代码表示一个函数,该函数传递一个由两列(Date(CLass = Date)和Discharge Data(Class = Numeric)组成的数组,用于计算月平均值。因此,firstDate和lastDate是类Date,并由传递数组。这段代码改编自成功的代码,用于计算年平均值 - 可能还有一两件事我仍然需要更改,但由于我在使用POSIXlt时出现的早期错误,因此无法对以后的部分进行错误检查这是代码:

MonthlyAvgDischarge<-function(values){  

  #determining the number of values - i.e. the number of rows
  dataCount <- nrow(values)

  # Determining first and last dates
  firstDate <- (values[1,1])
  lastDate <- (values[dataCount,1])

  # Setting up vectors for results
  WaterMonths <- numeric(0)
  class(WaterMonths) <- "Date"
  numDays <- numeric(0)
  MonthlyAvg <- numeric(0)

  # while loop variables
  loopDate1 <- firstDate
  loopDate2 <- firstDate

  # Setting up the first inner while-loop controller, the start of the next water month
  NextH2OMonth <- as.POSIXlt(firstDate)
  NextH2OMonth$mon <- NextH2OMonth$mon + 1
  NextH2OMonth <- as.Date(NextH2OMonth)

  # Variables used in the loops
  dayCounter <- 0
  dischargeTotal <- 0
  dischargeCounter <- 1
  resultsCounter <- 1
  loopCounter <- 0
  skipcount <- 0

  # Outer while-loop, controls the progression from one year to another
  while(loopDate1 <= lastDate)
  {
    # Inner while-loop controls adding up the discharge for each water year
    # and keeps track of day count
    while(loopDate2 < NextH2OMonth)
    {
      if(is.na(values[resultsCounter,2]))
      {
        # Skip this date
        loopDate2  <- loopDate2 + 1
        # Skip this value
        resultsCounter <- resultsCounter + 1
        #Skipped counter
        skipcount<-skipcount+1
      } else{
        # Adding up discharge
        dischargeTotal <- dischargeTotal + values[resultsCounter,2]
      }

      # Adding a day
      loopDate2  <- loopDate2 + 1
      #Keeping track of days
      dayCounter <- dayCounter + 1
      # Keeping track of Dicharge position
      resultsCounter <- resultsCounter + 1
    }

    # Adding the results/water years/number of days into the vectors
    WaterMonths <- c(WaterMonths, as.Date(loopDate2, format="%mm/%Y"))
    numDays <- c(numDays, dayCounter)
    MonthlyAvg <- c(MonthlyAvg, round((dischargeTotal/dayCounter), digits=0))

    # Resetting the left hand side variables of the while-loops 
    loopDate1 <- NextH2OMonth
    loopDate2 <- NextH2OMonth

    # Resetting the right hand side variable of the inner while-loop
    # moving it one year forward in time to the next water year
    NextH2OMonth <- as.POSIXlt(NextH2OMonth)
    NextH2OMonth$year <- NextH2OMonth$Month + 1
    NextH2OMonth<-as.Date(NextH2OMonth)

    # Resettting vraiables that need to be reset
    dayCounter <- 0 
    dischargeTotal <- 0
    loopCounter <- loopCounter + 1
  } 

  WaterMonths <- format(WaterMonthss, format="%mm/%Y")
  # Uncomment the line below and return AvgAnnualDailyAvg if you want the water years also 
  # AvgAnnDailyAvg <- data.frame(WaterYears, numDays, YearlyDailyAvg) 
  return((MonthlyAvg))
}  

在常规R中发生相同的错误。当逐行执行时,它不是问题,当它作为脚本运行时,就是它。

3 个答案:

答案 0 :(得分:1)

Plain R

seq(Sys.Date(), length = 2, by = "month")[2]
seq(Sys.Date(), length = 2, by = "year")[2]

请注意,这也适用于POSIXlt,例如

seq(as.POSIXlt(Sys.Date()), length = 2, by = "month")[2]

<强> mondate 即可。

library(mondate)
now <- mondate(Sys.Date())
now + 1  # date in one month
now + 12  # date in 12 months

Mondate对于mondate("2013-01-31")+ 1这样的事情有点聪明,它给出了2月的最后一天,而seq(as.Date("2013-01-31"), length = 2, by = "month")[2]给出了3月3日。

yearmon 如果你真的不需要这一天的部分,那么yearmon可能会更好:

library(zoo)
now.ym <- yearmon(Sys.Date())
now.ym + 1/12 # add one month
now.ym + 1 # add one year

POSIXltyearmon上的部分添加了评论。

答案 1 :(得分:0)

您可以使用包lubridate

在R中添加1个月的日期
library(lubridate)
x <- as.POSIXlt("2010-01-31 01:00:00")
month(x) <- month(x) + 1

>x
[1] "2010-03-03 01:00:00 PST"

(请注意,它正确处理了添加,因为2月31日不存在)。

答案 2 :(得分:0)

你能提供一个可重复的例子吗? firstDate中的内容是什么,以及您使用的是哪个版本的R?我经常对POSIXlt日期进行这种操作,它似乎有效:

Sys.Date()
# [1] "2013-02-13"
date = as.POSIXlt(Sys.Date())
date$mon = date$mon + 1
as.Date(date)
# [1] "2013-03-13"