R 仅给定日期向量,展开(不相等)日期点之间的数据

R 仅给定日期向量,展开(不相等)日期点之间的数据,r,date,cumsum,R,Date,Cumsum,其他问题围绕着开始和结束日期。(有关示例,请参见下文。) 我的问题是不同的,因为我只有一个日期列,我想将不相等的日期范围转换为每日计数。这个特定的示例创建了一个工作站点上的工人数量。不同的人员在不同的日期出现 提供的简要数据框架如下: dd <- data.frame(date=as.Date(c("1999-03-22","1999-03-29","1999-04-08")),work=c(43,95,92),cumwork=c(43,138,230)) dd一种可能的方法: 首先,

其他问题围绕着开始和结束日期。(有关示例,请参见下文。)

我的问题是不同的,因为我只有一个日期列,我想将不相等的日期范围转换为每日计数。这个特定的示例创建了一个工作站点上的工人数量。不同的人员在不同的日期出现

提供的简要数据框架如下:

dd <- data.frame(date=as.Date(c("1999-03-22","1999-03-29","1999-04-08")),work=c(43,95,92),cumwork=c(43,138,230))
dd一种可能的方法:

首先,将您感兴趣的日期序列创建为一列数据框:

v <- data.frame(date = seq(min(dd$date), as.Date("1999-04-10"), by="day"))
NB:我假设您的数据帧
dd
实际上包含日期(而不是因子)


dd一种类似的解决方案,带有基本R(和
zoo
package):


dd$date这里有一个非常快速的纯base R解决方案:

ExpandDates <- function(df, lastColRepeat) {
    myDiff <- diff(df$date)
    dfOut <- data.frame(df$date[1] + 0:(sum(myDiff) + lastColRepeat - 1L),
                     stringsAsFactors=FALSE)
    myDiff <- c(myDiff, lastColRepeat)
    for (i in 2:3) {dfOut[,i] <- rep(df[ ,i], times = myDiff)}
    names(dfOut) <- names(df)
    dfOut
}
基准:

library(microbenchmark)
microbenchmark(DplyrTest(testDF), ExpandDates(testDF,1))
Unit: milliseconds
                  expr       min        lq      mean    median        uq       max neval cld
     DplyrTest(testDF) 80.909303 84.337006 91.315057 86.320883 88.818739 173.69395   100   b
ExpandDates(testDF, 1)  1.122384  1.208184  2.521693  1.355564  1.486317  72.23444   100  a 

检查这个链接na.locf函数真的很好!从来都不知道这个命令。所有的解决方案都有效,但最终选择@Scarabee one,因为代码简单明了,而且是管道式的。
dd <- data.frame(date=as.Date(c("1999-03-22","1999-03-29","1999-04-08")),work=c(43,95,92),cumwork=c(43,138,230))
dd$date <- as.Date(as.character(dd$date))
my.seq <- data.frame(date=seq.Date(from=range(dd$date)[1], to=range(dd$date)[2], by="day"))
output <- merge(my.seq, dd, all.x=TRUE)
output <- zoo::na.locf(output)
ExpandDates <- function(df, lastColRepeat) {
    myDiff <- diff(df$date)
    dfOut <- data.frame(df$date[1] + 0:(sum(myDiff) + lastColRepeat - 1L),
                     stringsAsFactors=FALSE)
    myDiff <- c(myDiff, lastColRepeat)
    for (i in 2:3) {dfOut[,i] <- rep(df[ ,i], times = myDiff)}
    names(dfOut) <- names(df)
    dfOut
}
set.seed(123)
workVec <- sample(5000, 3000)
testDF <- data.frame(date = as.Date(sort(sample(12000, 3000)), 
                                    origin = "1970-01-01"), work = workVec, 
                                                    cumwork = cumsum(workVec))

DplyrTest <- function(dd) {  ## from @Scarabee
    v <- data.frame(date = seq(min(dd$date), max(dd$date), by="day"))
    v %>% 
        left_join(dd, by = "date") %>% 
        na.locf
}

a <- ExpandDates(testDF, 1)
b <- DplyrTest(testDF)
identical(a$cumwork, as.integer(b$cumwork))
[1] TRUE
identical(a$work, as.integer(b$work))
[1] TRUE
identical(a$date, as.Date(b$date))
[1] TRUE
library(microbenchmark)
microbenchmark(DplyrTest(testDF), ExpandDates(testDF,1))
Unit: milliseconds
                  expr       min        lq      mean    median        uq       max neval cld
     DplyrTest(testDF) 80.909303 84.337006 91.315057 86.320883 88.818739 173.69395   100   b
ExpandDates(testDF, 1)  1.122384  1.208184  2.521693  1.355564  1.486317  72.23444   100  a