R如果开始和结束时间可用,则每天汇总数据

R如果开始和结束时间可用,则每天汇总数据,r,time,time-series,aggregate,transformation,R,Time,Time Series,Aggregate,Transformation,我有以下问题。我有以下结构的数据帧: startdatetime enddatetime type amount 1 2019-02-01 03:35:00 2019-02-03 06:35:00 prod1 1e+03 2 2019-02-03 06:35:00 2019-02-05 09:35:00 prod1 5e+03 3 2019-02-05 09:35:00 2019-02-06 01:35:00 prod2 3e+07 4 2019-02-0

我有以下问题。我有以下结构的数据帧:

        startdatetime         enddatetime  type amount
1 2019-02-01 03:35:00 2019-02-03 06:35:00 prod1  1e+03
2 2019-02-03 06:35:00 2019-02-05 09:35:00 prod1  5e+03
3 2019-02-05 09:35:00 2019-02-06 01:35:00 prod2  3e+07
4 2019-02-06 01:35:00 2019-02-06 03:35:00 prod1  1e+02
表示在特定时间跨度(startdatetime和enddatetime)内产生的量。现在我想每天汇总这些数据。让我们忽略不完整的2019-02-01日,从2019-02-02开始。第一个产品1于2019-02-01 03:35:00至2019-02-03 06:35:00期间生产,共生产1000千克。例如,在2019-02-02年:
24/51*1000
=470.58生产产品1,因为
24h+21h+6h=51h
。 到目前为止,我的解决方案是基于for和while循环的,但我想有一个更快的解决方案是基于包“lubridate”的,或者我没有找到的。 有什么建议吗? 在我的代码下面

#create test data set
mydata <- data.frame(startdatetime=c(as.POSIXct("2019-02-01 03:35:00"), as.POSIXct("2019-02-03 06:35:00"),as.POSIXct("2019-02-05 09:35:00"),as.POSIXct("2019-02-06 01:35:00")),
                     enddatetime  =c(as.POSIXct("2019-02-03 06:35:00"), as.POSIXct("2019-02-05 09:35:00"),as.POSIXct("2019-02-06 01:35:00"),as.POSIXct("2019-02-06 03:35:00")),
                     type=c("prod1","prod1","prod2","prod1"),
                     amount=c(1000,5000,30000000,100)) 

# take only full days into account and ignore the first and the last day
minstartday = min(mydata$startdatetime)+24*60*60
maxendday   = max(mydata$enddatetime)-24*60*60

#create a day index
timesindex <- seq(from = as.Date(format(minstartday, format = "%Y/%m/%d")), 
                  to   = as.Date(format(maxendday, format = "%Y/%m/%d")), by = "day")

# create an empty dataframe which will be filled with the production data for each day
prodperday <- data.frame(Date=as.Date(timesindex),
                         prod1=replicate(length(timesindex),0), 
                         prod2=replicate(length(timesindex),0), 
                         stringsAsFactors=FALSE) 

# loop over all entries and separate them into produced fractions per day
for (irow in 1:dim(mydata)[1]){
  timestart = mydata[irow,"startdatetime"]
  datestart = as.Date(format(timestart, format = "%Y/%m/%d"))
  timeend = timestart
  tota_run_time_in_h = (as.numeric((mydata[irow,"enddatetime"]-mydata[irow,"startdatetime"])))*24.
  while (timeend < mydata[irow,"enddatetime"]){
    timeend = min (as.POSIXct(datestart, format = "%Y/%m/%d %H:%M:%S")+23*60*60-1,
                   mydata[irow,"enddatetime"])
    tdiff = as.numeric(timeend-timestart)
    fraction_prod = (tdiff/tota_run_time_in_h)*mydata[irow,"amount"]
    if (datestart %in% prodperday$Date){
      prodperday[prodperday$Date == datestart,as.character(mydata[irow,"type"])] = 
        prodperday[prodperday$Date == datestart,as.character(mydata[irow,"type"])] + fraction_prod
    }

    timestart = timeend+1
    datestart = as.Date(format(timestart, format = "%Y/%m/%d"))
    timeend = timestart
  }
}

我提出的解决方案并不完美,因为存在边界问题,但在生产过程中按小时转换数据,然后按天聚合数据可能是个好主意

我使用了两个库:

library(lubridate)
library(dplyr)
参考时间:

ref.times <- seq(from = min(mydata$startdatetime),
           to = max(mydata$enddatetime),
           by = "hour")

我提出的解决方案并不完美,因为存在边界问题,但在生产过程中按小时转换数据,然后按天聚合数据可能是个好主意

我使用了两个库:

library(lubridate)
library(dplyr)
参考时间:

ref.times <- seq(from = min(mydata$startdatetime),
           to = max(mydata$enddatetime),
           by = "hour")

下面是我要做的:

您知道开始日期使用的是
24个开始时间
生产小时。结束日期使用
endtime
hours,其间的所有日期显然都使用24小时。所以它很容易计算

library(lubridate)
library(tidyverse)

pmap_dfr(mydata, ~ {
  hours       <- abs(as.numeric(difftime(..1, ..2, units = "hours")))
  day_seq     <- seq(as_date(..1), as_date(..2), by = "days")
  hours_start <- hour(..1) + minute(..1) / 60
  hours_end   <- hour(..2) + minute(..2) / 60

  production  <- c(
    ..4 * (24 - hours_start) / hours,
    rep(..4 * 24 / hours, max(length(day_seq) - 2, 0)),
    ..4 * hours_end / hours
  )
  tibble(
    day = day_seq,
    amount = production,
    type = ..3
  )
}) %>%
  group_by(day, type) %>%
  summarise(amount = sum(amount)) %>%
  spread(type, amount) %>%
  replace_na(list(prod1 = 0, prod2 = 0))


# A tibble: 6 x 3
# Groups:   day [6]
  day        prod1     prod2
  <date>     <dbl>     <dbl>
1 2019-02-01  400.        0 
2 2019-02-02  471.        0 
3 2019-02-03 1837.        0 
4 2019-02-04 2353.        0 
5 2019-02-05  940. 27031250 
6 2019-02-06 1300.  2968750.
库(lubridate)
图书馆(tidyverse)
pmap_dfr(mydata,~{

小时数以下是我要做的:

您知道,开始日期使用的是
24开始时间
生产小时数。结束日期使用的是
endtime
小时数,两者之间的所有天数显然都使用24小时。因此,计算起来很容易

library(lubridate)
library(tidyverse)

pmap_dfr(mydata, ~ {
  hours       <- abs(as.numeric(difftime(..1, ..2, units = "hours")))
  day_seq     <- seq(as_date(..1), as_date(..2), by = "days")
  hours_start <- hour(..1) + minute(..1) / 60
  hours_end   <- hour(..2) + minute(..2) / 60

  production  <- c(
    ..4 * (24 - hours_start) / hours,
    rep(..4 * 24 / hours, max(length(day_seq) - 2, 0)),
    ..4 * hours_end / hours
  )
  tibble(
    day = day_seq,
    amount = production,
    type = ..3
  )
}) %>%
  group_by(day, type) %>%
  summarise(amount = sum(amount)) %>%
  spread(type, amount) %>%
  replace_na(list(prod1 = 0, prod2 = 0))


# A tibble: 6 x 3
# Groups:   day [6]
  day        prod1     prod2
  <date>     <dbl>     <dbl>
1 2019-02-01  400.        0 
2 2019-02-02  471.        0 
3 2019-02-03 1837.        0 
4 2019-02-04 2353.        0 
5 2019-02-05  940. 27031250 
6 2019-02-06 1300.  2968750.
库(lubridate)
图书馆(tidyverse)
pmap_dfr(mydata,~{

小时Thx,我在数据子集(500行)上进行了尝试。此版本耗时58秒。我在问题中发布的版本耗时28秒,因此速度大约是此版本的两倍。如果要应用此版本,他/她需要确保startdatetime和endtdatetime定义为字符,并且格式正确。否则,解决方案将抛出错误:')as.posixlt.character(x tz…)字符串不是标准的明确格式“Thx”,我在数据子集(500行)上尝试了它。此版本耗时58秒。我在问题中发布的版本耗时28秒,因此速度大约是此版本的两倍。如果要应用此版本,他/她需要确保startdatetime和endtdatetime定义为字符,并且格式正确。否则,解决方案将抛出错误:')as.posixlt.character(x tz…)字符串不是标准的明确格式“Thx”:在newdata声明中,它必须是ref.times,而不是newdata$hour。我测试了解决方案,它花费的时间是我的解决方案的两倍多,是@erocoarThx解决方案的5倍多:在newdata声明中,它必须是ref.times,而不是newdata$hour。I te测试了该解决方案,所用时间是我的解决方案的两倍多,是@erocoar解决方案的5倍多