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



其他问题集中在开始和结束日期上。(有关示例,请参阅以下内容 给定开始日期和结束日期,调整/展开每天的数据(每天在一行中( 使用开始日期和结束日期按日期范围扩展行

我的问题是不同的,因为我只有一个日期列,我想将不相等的日期范围转换为每日计数。此特定示例创建处理一次作业现场的工人数量。不同的船员在不同的日期来

提供的简要数据框如下:

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

我希望数据看起来像这样:

dw <- data.frame(date=c(seq(as.Date("1999-03-22"),as.Date("1999-04-10"),by= "day")),
work=c(rep(43,7),rep(95,10),rep(92,3)),
cumwork=c(rep(43,7),rep(138,10),rep(230,3)))

我已经坚持了一段时间了。任何帮助将不胜感激!

更新(7/5/2017(:正如@Scarabee所指出的,数据帧"dd"中的日期应采用日期格式。已更新代码以反映这一点

一种可能的方法:

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

v <- data.frame(date = seq(min(dd$date), as.Date("1999-04-10"), by="day"))

接下来,使用原始数据帧联接并填充缺失值,例如使用dplyrzoo

library(dplyr)
library(zoo)
v %>% 
left_join(dd, by = "date") %>% 
na.locf

注意:我想你的数据帧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))

一个类似的解决方案,具有基本 R(和zoo包(:

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)

您首先必须将日期转换为日期格式。然后分别创建一个完整日期的向量并将其与原始数据合并。最终,运行"最后观察结转"算法。

这是一个非常快速的纯基础 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
}

最后一个参数是确定最后一个值应重复的次数。就目前而言,原始 data.frame 中没有任何内容可以给出此值。 我还假设"日期"字段实际上是@Scarabee指出的日期。

以下是一些测试数据:

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 

最新更新