矩阵错误 - 数据长度不匹配,即使它应该

时间:2014-08-24 16:34:22

标签: r matrix vector runtime-error

我正在尝试编写一个函数,它将返回两个日期之间的工作日数(不仅仅是排除周末,还包括假日)。我正在接近它,通过构建一个矩阵,其中rownames对应于星期几,矩阵的元素为1或0:如果是假日则为0,或者填充矩阵的额外元素元素。

我已经检查了代码中每个向量的长度。它结账了。我在控制台中手动运行代码,一次一行,它完美地运行。但是,如果我运行该功能,它会显示以下错误消息:

Warning message:
In matrix(da, nrow = 7, dimnames = list(n)) :
  data length [132] is not a sub-multiple or multiple of the number of rows [7]

我正在使用R 3.1.1,主要在Rstudio工作。代码中提到的cal可以找到here

以下是代码:

dte <- function(date) {
#Input a date and it tells you the number of business (not including holidays) 
#days until that date

        #Take the target date and turn it into a date
        d <- strptime(date,format="%Y-%m-%d")

        #Obtain current date
        c <- strptime(Sys.Date(), format="%Y-%m-%d")

        #Calculate the difference in days
        diff <- d-c

        #Extract the actual number difference
        f <- diff[[1]]

        #Get the list of holidays
        cal <- dget("cal")
        cal <- as.Date(cal)

        #Get the full list of dates between now and the target date
        b <- Sys.Date()+0:f

        #Find which days in the range are holidays
        if(any(b %in% cal)) {
                bt <- b[b %in% cal]

                #Return the position of the holidays within the range
                bn <- which(b %in% bt)
        } else {
                #Set holidays present to 0
                bn <- 0
        }

        #Build a vector of the weekdays starting with the current weekday
        n <- weekdays(Sys.Date()+0:6) 

        #Create a vector as long as the difference with a 1 in each place
        v <- rep(1,f)

        #Set each holiday to 0
        v[bn] <- v[bn]-1

        #Extra steps to make sure that the matrix is full but only with 1s where we want them.
        g <- ((trunc(f/7)+1)*7)-f
        u <- rep(0,g)
        da <- c(v,u)

        #Create the matrix
        m <- matrix(da,nrow=7,dimnames=list(n))

        #Extract all of the workweeks and add them up
        ww <- m[c("Monday","Tuesday","Wednesday","Thursday","Friday"),]
        r <- sum(ww)               
        r
}

1 个答案:

答案 0 :(得分:0)

问题是你的strptime调用返回了具有时间组件的POSIXt对象,然后受到夏令时的影响。观察

(d1<-strptime("2014-08-24",format="%Y-%m-%d"))
# [1] "2014-08-24 EDT"
(d2<-strptime("2014-12-31",format="%Y-%m-%d"))
# [1] "2014-12-31 EST"
d2-d1
# Time difference of 129.0417 days

因此,这两个值之间没有一定数量的日期会导致您的代码稍后出现问题。如果您使用的是as.Date而不是strptime,那么您就不会遇到此问题,因为日期对象并不关心时间。

但我不确定为什么你甚至根本不打扰矩阵。我认为更简单的实现看起来像

dte <- function(date) {
    d <- as.Date(date,format="%Y-%m-%d")
    c <- Sys.Date()

    cal <- dget("cal")
    cal <- as.Date(cal)

    #Get the full list of dates between now and the target date
    b <- seq(c, d, by="1 day")

    return(sum(as.POSIXlt(b)$wday %in% 1:5 & (!b %in% cal)))
}