Мои данные выглядят так:
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)))))
Мне удалось рассчитать разницу в датах (в днях), как в столбце «Разница дат».
Если я вычислю среднее значение на основе разницы дат, результатом будет среднее количество дней между всеми тестами.
Теперь я хотел бы знать среднее количество дней между 1-м и 2-м, 2-м и 3-м тестами ect.., потому что я хочу знать, становятся ли интервалы короче/длиннее.
Это вообще возможно?
Вы можете создать столбец с номером теста для каждого пациента, а затем для каждого номера теста рассчитать среднее значение 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
Я не уверен, почему вы получите эту ошибку. У меня этого не происходит для данных, которыми вы поделились. Попробуйте перезапустить R и загрузить только dplyr
и запустить ответ. Есть такие функции, как summarise
/mutate
, которые могут быть замаскированы от plyr
.
Вы можете использовать отставание, чтобы создать столбец смещения в вашем фрейме данных и найти дуарацию интервала, вот решение с 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
лучше для группового применения функций для создания новых столбцов, то есть разницы дат в вашем случае. Он уже возвращает векторы и избегает unlist
ing.
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
теперь удобно составлять таблицы по группам. Мы можем использовать его здесь, чтобы очень легко вычислить diff
значения mean.Date
s. (`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")
Спасибо за ваш ответ. Это кажется очень хорошим решением. Однако я получаю сообщение об ошибке: Ошибка в
$<-.data.frame
(*tmp*
, Date.diff, value = list(test_number = 1:47, : замена имеет 47 строк, данные имеют 486. Есть идеи, как решить эту ошибку?