【问题标题】:R - Intervals of date & Number of rows by dateR - 日期间隔和按日期排列的行数
【发布时间】:2018-12-17 00:18:54
【问题描述】:

我有一个关于计算日期间隔的更快方法的问题

我的意见:

  • 一个数据框:一行一行(人,期间)。在每一行,我都有一个人的 ID、开始日期和结束日期。
  • 一段时间:两年内的所有日期

我尝试做的是按日期计算我拥有的人数。 我有一个正在运行的代码,但对于大型数据集(〜从 100 k 到 1 M 行)来说效率不够。

目前的问题是因为我有两年的约会,我的代码执行了 730 次(365x2)以下步骤:

  • 使用包含在开始日期和结束日期之间的特定日期过滤数据集
  • 计算过滤数据集中唯一ID的数量 对于大型数据集,这些操作非常耗时或不可能

我想知道是否存在更好更快的方法来执行这些操作,例如使用聚合或其他技术。

一个短输入和输出的例子:

library(lubridate)
library(dplyr)

# Vector of date
vector_day <- seq(ymd('2017-01-01'), ymd('2018-12-30'), by= "days")

# Input Data
df <- data.frame(
      id_people = c(1, 2, 3, 4, 1),
      StartDate = c(as.Date("2018-11-01"), as.Date("2018-11-03"),as.Date("2018-12-01"),as.Date("2018-11-15") ,as.Date("2018-11-15")),
      EndDate = c(as.Date("2018-11-10"), as.Date("2018-12-04"),as.Date("2018-12-10"),as.Date("2018-11-17"), as.Date("2018-11-23")), 
      Gender = c("F", "F", "M", "F", "F"))


# Function to compute the number of people given a spécific date
compute_nb_f_by_day <- function(date) {

  cond1 <- df_f$StartDate <= date
  cond2 <- df_f$EndDate > date
  cond <- cond1 & cond2

  res <- length(unique(df_f[cond,]$id_people))
  return(res)

}

# An example of how the function works for on date
compute_nb_f_by_day(as.Date("2018-12-01"))

# Computation for all the dates
nb_f_by_day <- cbind(
               data.frame(vector_day),
               data.frame(nb_f_by_day <- sapply(vector_day, compute_nb_f_by_day)))

谢谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    此解决方案的基准测试速度明显快于给定示例中的代码(您的代码:0.132s;此代码:在我的系统中为 0.032s)。试试看它是否会显着改善大型数据集!

    #-- Create the 'Interval'
    df2 <- df %>%
      mutate(DateInterval = StartDate %--% EndDate)
    
    #-- Create a result df instead of using cbind (more efficient)
    result_df <- data.frame(Day = vector_day, Nb = NA)
    
    #-- Get intervals that contain the days in vector_day
    result_df$Nb <- sapply(vector_day, function(day) {sum(day %within% df2$DateInterval)})
    

    【讨论】:

    • 非常感谢,我没有准确测量速度的增益,但在我的大型数据集下它明显更快。
    最近更新 更多