【问题标题】:R calculating time differences in a (layered) long datasetR计算(分层)长数据集中的时间差
【发布时间】:2020-11-18 14:19:04
【问题描述】:

我一直在为一些时间戳数据而苦苦挣扎(直到现在,我还没有过多地处理日期,它显示了)。希望你能帮忙。

我正在处理来自网站的数据,该数据显示每个客户 (ID) 的各自访问以及这些访问的时间戳。它的分组意味着一位客户可能有多次访问/时间戳。

df 的结构如下,采用长格式:

 df <- data.frame("Customer" = c(1, 1, 1, 2, 3, 3),  
                  "Visit" =c(1, 2, 3, 1, 1, 2), # e.g. customer ID #1 has visited the site three times.
                  "Timestamp" = c("2019-12-31 12:13:25", "2019-12-31 16:13:25", "2020-01-05 10:13:25", "2019-11-12 15:18:42", "2019-11-13 19:22:35", "2019-12-10 19:43:55"))

注意:在实际数据集中,时间戳不是一个因素,而是其他一些憔悴的字符类型可憎,我可能应该首先尝试以某种方式将其转换为 POSIXct 格式。

我想做的是创建一个 df,显示每位客户的平均访问时间(比如说以分钟或小时为单位)。只有一次访问的访问者(例如,我的示例中的第二个客户)可能会被提前过滤掉,或者应该显示为 0。我的最终目标是可视化该分布,并可能计算所有客户的总体平均值。

因为访问次数可能会有很大差异(例如 1 次或 256 次访问),所以我不能只使用数据集的“宽”版本,其中固定访问次数是我可以减去并平均的列。

我不知道如何最好地解决这类问题,非常感谢!

【问题讨论】:

  • 在下面添加到我的 cmets:我的大部分职业时间都花在争论时间戳上。只要时间戳格式与 Y-m-d H:M:S 略有不同,lubridate 包就会使事情变得容易得多。

标签: r datetime


【解决方案1】:

使用 dplyr:

df %>%
  arrange(Customer, Timestamp) %>%
  group_by(Customer) %>%
  mutate(Difference = Timestamp - lag(Timestamp)) %>%
  summarise(mean(Difference, na.rm = TRUE))

由于分组,任何客户的第一个差异值应该是NA(包括那些只有一次访问的客户),所以他们将被平均丢弃。

【讨论】:

    【解决方案2】:

    使用基础 R(没有额外的包):

    1. 对数据进行排序,按客户 ID 排序,然后按时间戳。
    2. 计算连续行之间的时间差(使用diff() 函数),按客户ID 分组(tapply() 进行分组)。
    3. 求平均值
    4. 将其压缩成data.frame
    # 1 sort the data
    df$Timestamp <- as.POSIXct(df$Timestamp)
    # not debugged 
    df <- df[order(df$Customer, df$Timestamp),]
    
    # 2 apply a diff. 
    # if you want to force the time units to seconds, convert
    # the timestamp to numeric first.
    
    # without conversion
    diffs <- tapply(df$Timestamp, df$Customer, diff)
    # ======OR======
    # convert to seconds
    diffs <- tapply(as.numeric(df$Timestamp), df$Customer, diff)
    
    # 3 find the averages
    diffs.mean <- lapply(diffs, mean)
    
    # 4 squish that into a data.frame
    diffs.df <- data.frame(do.call(rbind, diffs.mean))
    diffs.df$Customer <- names(diffs.mean)
    
    # 4a tidy up the data.frame names
    names(diffs.df)[1] <- "Avg_Interval"
    diffs.df
    

    您尚未显示您的时间戳字符串,但当您需要处理它们时,lubridate 包是您的朋友。

    【讨论】:

    • 感谢这个技巧,它看起来比 dplyr 替代品更快(在完整数据集上)。您是否碰巧知道在这种情况下的默认时间单位是什么?我想它是几秒钟。
    • 您可以使用diff(as.numeric(df$Timestamp)) 将其强制为秒。我会更新答案以显示它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多