【问题标题】:Grouping similar times together将相似的时间分组在一起
【发布时间】:2023-03-11 20:45:02
【问题描述】:

我有一个包含收缩压和日期/时间的数据框。这些读数有时是在几分钟内完成的,有时不是。下面是一个例子:

library(tidyverse)

date_time <- c("Jan 29 2020 13:46:08" , 
              "Jan 29 2020 13:42:53" , 
              "Jan 29 2020 12:13:27" ,
              "Jan 29 2020 12:11:19" , 
              "Jan 29 2020 12:09:21" , 
              "Jan 28 2020 12:22:26" , 
              "Jan 27 2020 8:22:20")

systol <- c(132  , 132  , 118  , 115  , 110 , 148 , 120)

df <- data.frame(date_time , systol) %>%
  mutate(dtetime = lubridate::mdy_hms(date_time)

我想将在时间上彼此靠近的收缩压读数进行分组——任意分组,最后一次读数在任何组中第一次读数的 10 分钟内进行——并对读数进行平均(理想情况下是对日期/时间进行平均)的阅读以及)。我已经尝试通过使用滞后和前导函数以及 group_by 来考虑它,如果一组中没有 2 个读数,我无法设计出一种方法来做到这一点。我对 tidyverse 最熟悉,所以更喜欢这种方法,但我对任何方式都感兴趣。我对 R 比较陌生。感谢您的帮助!

【问题讨论】:

  • 您能否显示共享数据的预期输出?

标签: r datetime grouping


【解决方案1】:

这是一种使用data.table的方法:

library(data.table)
dt <- as.data.table(df)

> dt[, .(mean_value = mean(systol)), by = .(mean_time = lubridate::round_date(x = dtetime, unit = '10 min'))]
             mean_time mean_value
1: 2020-01-29 13:50:00   132.0000
2: 2020-01-29 13:40:00   132.0000
3: 2020-01-29 12:10:00   114.3333
4: 2020-01-28 12:20:00   148.0000
5: 2020-01-27 08:20:00   120.0000

我正在使用round_date,顾名思义,它会将时间四舍五入到最接近的 10 分钟,您还可以查看floor_date 或其他选项以获得所需的输出。

【讨论】:

  • 我认为这不能解决问题。在 dt 中,第 1 行和第 2 行位于不同的组中,因为 df 的第 1 行从 13:46 到 13:50 向上取整,第 2 行从 13:42 到 13:40 向下取整——它们应该在同一组,因为它们在 10 分钟内。
  • 如何定义时间的“锚”点,例如如果您有 3 次(仅显示分钟):9、11、13、20、23 并且您选择 13 作为时间锚点,则所有条目都将包含在 avg 中。但是,如果您选择 20,则“9”将被排除在外,因为它超出了任一侧的 10 分钟范围。或者您是否想保留原始时间戳和原始测量值并获得等于平均值​​的新测量值。在上述观察后 10 分钟内发生了什么?你能分享一个更大的例子和你想要的确切结果吗?
  • 以df为例,这是我想要的结果: group 1: rows 1 and 2 group2: rows 3, 4, 5 group3: row 6 group 4: row 7 对象是以平均在时间上彼此接近的读数,因为它们可以被看作是聚集的。 “及时关闭”的标准是所有读数都在 10 分钟内获得——即。任何组的最后一次阅读必须在该组第一次阅读的 10 分钟内。组可以有任意数量的读数,只要组符合标准。我相信 df 显示了问题的复杂性。这说明清楚了吗?
  • 附言。也许将这些显示为一个人的读数会有所帮助。
【解决方案2】:

基本上使用cut。在ordering 越来越多的读数之后,制作一个与第一次读数的差异向量,

d <- d[order(d$dtetime), ]  ## order readings increasingly
dff <- with(d, as.numeric(dtetime) - as.numeric(dtetime)[1])  ## calc. diff from 1st reading

允许创建 10 分钟的垃圾箱(以秒为单位)。

bins <- seq(min(dff), max(dff)*1.24, 10 * 60)  ## 10 min bins

现在我们可以 cut 在这些垃圾箱中分组并计算 means 的时间和 systol,同时 aggregateing 沿着它们。

d$group <- cut(dff, breaks=bins, include.lowest=TRUE)
res <- aggregate(cbind(dtetime, systol) ~ group, d, mean)[-1]
res$dtetime <- as.POSIXct(res$dtetime, origin="1970-01-01")  ## converting back to POSIX 
res
#               dtetime systol
# 1 2020-01-27 08:22:20  120.0
# 2 2020-01-28 12:22:26  148.0
# 3 2020-01-29 12:10:20  112.5
# 4 2020-01-29 12:13:27  118.0
# 5 2020-01-29 13:44:30  132.0

数据:

date_time <- c("Jan 29 2020 13:46:08", "Jan 29 2020 13:42:53", "Jan 29 2020 12:13:27", 
               "Jan 29 2020 12:11:19", "Jan 29 2020 12:09:21", "Jan 28 2020 12:22:26", 
               "Jan 27 2020 8:22:20")
systol <- c(132, 132, 118, 115, 110, 148, 120)
d <- data.frame(dtetime=strptime(date_time, format="%b %e %Y %H:%M:%S") , systol)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-26
    相关资源
    最近更新 更多