如何按组计算平均时间差?

How to calculate average time differences by group?

我的数据是这样的:

data <- read.table(header=T, text= '
 PID     Date           Date.diff
  1      2020-01-01     0 
  1      2020-01-02     1
  1      2020-01-10     8
  2      2020-01-15     0
  3      2020-01-02     0
  4      2020-02-02     0
  4      2020-03-01     28
  4      2020-04-15     45
  ..     ..
 ')

每个日期指的是(在本例中)患者完成测试的日期。

使用此代码:

data$Date.diff <- unlist(tapply(data$Date, INDEX=data$PID, FUN=function(x)
  c(0, diff(as.numeric(x)))))

我能够像日期差异列中那样计算日期差异(以天为单位)。

如果我根据日期差异计算平均值,结果将是所有测试之间的平均天数。

现在我想知道第一次和第二次、第二次和第三次等测试之间的平均天数,因为我想知道间隔是否达到 shorter/longer。

这可能吗?

您可以为每位患者创建一个测试编号列,然后为每个测试编号计算 Date.diff.

的平均值
library(dplyr)

data %>%
  group_by(PID) %>%
  mutate(test_number = row_number()) %>%
  group_by(test_number) %>%
  summarise(Date.diff = mean(Date.diff)) -> result
result

您可以使用 lag 在您的数据框中创建一个偏移列并找到间隔时间,这是一个使用 dplyr 和 lubridate 的解决方案:

library(dplyr)
library(lubridate)

data %>%
  mutate(across("Date", ymd)) %>%
  group_by(PID) %>%
  mutate(lag = lag(Date),
         diff2 = as.numeric(as.duration(interval(lag, Date)), "days")) %>%
  group_by(row_number()) %>%
  summarise(mean_days = mean(diff2, na.rm = TRUE), .groups = "drop")

# A tibble: 3 x 2
  `row_number()` mean_days
          <int>     <dbl>
1             1     NaN  
2             2      14.5
3             3      26.5

使用 ave 更好地按组应用函数以创建新列,即您的情况下的日期差异。它已经返回向量并避免 unlisting.

dat$Date.diff <- with(dat, ave(as.numeric(Date), PID, FUN=function(x) c(0, diff(x))))

head(dat)
# PID       Date Date.diff
# 1   1 2020-01-03         0
# 2   1 2020-01-03         0
# 3   1 2020-01-18        15
# 4   1 2020-01-24         6
# 5   1 2020-01-24         0
# 6   2 2020-01-05         0

tapply 现在对于按组制表非常有用。我们可以在这里使用它来非常容易地计算 mean.Datedifferences。 (`1`=0 只是装饰品)。

c(`1`=0, diff(with(dat, tapply(Date, PID, FUN=mean.Date))))
#   1    2    3    4    5 
# 0.0  9.0 16.2  4.4 21.6 

数据

dat <- structure(list(PID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L), 
    Date = structure(c(18264, 18264, 18279, 18285, 18285, 18266, 
    18281, 18286, 18291, 18298, 18287, 18295, 18303, 18308, 18310, 
    18288, 18297, 18304, 18310, 18326, 18302, 18319, 18332, 18335, 
    18345), class = "Date")), row.names = c(NA, -25L), class = "data.frame")