在R中使用POSIXlt向X添加一个月的问题需要使用as.Date(X)来重置值 [英] Problems adding a month to X using POSIXlt in R - need to reset value using as.Date(X)

查看:139
本文介绍了在R中使用POSIXlt向X添加一个月的问题需要使用as.Date(X)来重置值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这在R中适用于我:

 #设置第一个内循环控制器,下一个开始水年
NextH2OYear < - as.POSIXlt(firstDate)
NextH2OYear $ year < - NextH2OYear $ year + 1
NextH2OYear< -as.Date(NextH2OYear)

但这不是:

 #设置第一个内循环控制器,下一个水月开始
NextH2OMonth< - as.POSIXlt(firstDate)
NextH2OMonth $ mon < - NextH2OMonth $ mon + 1
NextH2OMonth< - as.Date(NextH2OMonth)

我得到这个错误: p>

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){

#确定号码的值 - 即行数
dataCount< - nrow(values)

#确定第一个和最后一个日期
firstDate < - (values [1,1])
lastDate< - (values [dataCount,1])$ ​​b
$ b#设置结果的向量
WaterMonths< - numeric(0)
class(WaterMonths) < - Date
numDays< - numeric(0)
MonthlyAv g< - numeric(0)

#while循环变量
loopDate1< - firstDate
loopDate2< - firstDate

#设置第一个内循环控制器,下一个水月开始
NextH2OMonth < - as.POSIXlt(firstDate)
NextH2OMonth $ mon < - NextH2OMonth $ mon + 1
NextH2OMonth< - as.Date(NextH2OMonth)

#循环中使用的变量
dayCounter < - 0
dischargeTotal< - 0
dischargeCounter < - 1
resultsCounter< - 1
loopCounter< - 0
skipcount< - 0

#外部循环,控制从一年到另一年
while(loopDate1 <= lastDate)
{
#内部while循环控制每个水年的排放
#并跟踪日数
while(loopDate2 < NextH2OMonth)
{
if(is.na(values [resultsCounter,2]))
{
#跳过这个日期
loopDate2< - loopDate2 + 1
#跳过这个值
resultsCounter< - resultsCounter + 1
#Skipped counter
skipcount< -skipcount + 1
} else {

dischargeTotal< - dischargeTotal + values [resultsCounter,2]
}

#添加一天
loopDate2< - loopDate2 + 1
#Keeping跟踪日子
dayCounter< - dayCounter + 1
#跟踪Dicharge位置
resultsCounter< - resultsCounter + 1
}

#添加结果/水年/向量的天数
WaterMonths< - c(WaterMonths,as.Date(loopDate2,format =%mm /%Y))
numDays< - c (numDays,dayCounter)
MonthlyAvg < - c(MonthlyAvg,round((dischargeTotal / dayCounter),digi ts = 0))

#重置while循环的左侧变量
loopDate1 < - NextH2OMonth
loopDate2 < - NextH2OMonth

#重置内部while循环的右侧变量
#将其一年前移到下一个水年
NextH2OMonth< - as.POSIXlt(NextH2OMonth)
NextH2OMonth $ year< - NextH2OMonth $ Month + 1
NextH2OMonth< -as.Date(NextH2OMonth)

#重新设置需要重置的可执行文件
dayCounter < - 0
dischargeTotal< - 0
loopCounter< - loopCounter + 1
}

WaterMonths< - 格式(WaterMonthss,format =%mm /%Y)
#取消注释下面的行并返回AvgAnnualDailyAvg如果你想要水年也
#AvgAnnDailyAvg< - data.frame(WaterYears,numDays,YearlyDailyAvg)
return((MonthlyAvg))
}

同样的错误发生在常规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

 库(mondate)
now< - mondate(Sys.Date())
now + 1#日期在一个月
现在+ 12#日期在12个月

Mondate是位对于$ 2 $ / code>,而$ seq(as.Date(2013​​)则更为明智的一点就是 mondate(2013-01-31)+ 1 -01-31),length = 2,by =month)[2] 给3月3日。



如果您真的不需要日间部分,那么 yearmon 可能更为可取:

  library(zoo)
now.ym< - yearmon(Sys.Date())
now.ym + 1/12#添加一个月
现在。 ym + 1#加一年

添加评论 POSIXlt yearmon的部分


This works for me in 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)

But this doesn't:

# 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)

I get this error:

Error in as.Date.POSIXlt(NextH2OMonth) : zero length component in non-empty POSIXlt structure

Any ideas why? I need to systematically add one year (for one loop) and one month (for another loop) and am comparing the resulting changed variables to values with a class of Date, which is why they are being converted back using as.Date().

Thanks, Tom

Edit:

Below is the entire section of code. I am using RStudio (version 0.97.306). The code below represents a function that is passed an array of two columns (Date (CLass=Date) and Discharge Data (Class=Numeric) that are used to calculate the monthly averages. So, firstDate and lastDate are class Date and determined from the passed array. This code is adapted from successful code that calculates the yearly averages - there maybe one or two things I still need to change over, but I am prevented from error checking later parts due to the early errors I get in my use of POSIXlt. Here is the code:

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))
}  

Same error occurs in regular R. When doing it line by line, its not a problem, when running it as a script, it it.

解决方案

Plain R

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

Note that this works with POSIXlt too, e.g.

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 is bit smarter about things like mondate("2013-01-31")+ 1 which gives last day of February whereas seq(as.Date("2013-01-31"), length = 2, by = "month")[2] gives March 3rd.

yearmon If you don't really need the day part then yearmon may be preferable:

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

ADDED comment on POSIXlt and section on yearmon.

这篇关于在R中使用POSIXlt向X添加一个月的问题需要使用as.Date(X)来重置值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆