基于固定日期间隔大小的移动窗口变异新列,在R中
我有 R 中一位患者的数据,其中显示了他们在某种情况下测试呈阳性的日期。数据如下所示:
date positive
2005-02-22 yes
2005-04-26 no
2005-08-02 yes
2005-10-04 no
2005-12-06 yes
2006-03-14 no
2006-06-06 no
2006-09-12 yes
2006-12-19 yes
2007-03-27 yes
现在我介绍一个新的定义。如果“当前测试为阳性,并且在之前 365 天内>=50% 的测试为阳性”,则将患者的状况定义为“慢性阳性”。所以我想创建一个输出数据集,告诉我患者在每个日期是否长期呈阳性。例如,输出应如下所示(例如,在 2006-09-12 上,它们是“阳性”但不是“慢性阳性”,因为在过去 365 天内的 4 次访问中有 3 次是阴性的):
date positive chronic
2005-02-22 yes no
2005-04-26 no no
2005-08-02 yes yes
2005-10-04 no no
2005-12-06 yes yes
2006-03-14 no no
2006-06-06 no no
2006-09-12 yes no
2006-12-19 yes no
2007-03-27 yes yes
我怎样才能做到这一点?在感兴趣的每一行中,我需要能够查看之前的行(在过去 365 天内)并评估它们的阳性比例。我想我可以使用lead/lag函数和的组合dplyr,但我很想知道如何做到这一点的例子。
原始数据可以通过以下方式复制:
dat <- structure(list(date = structure(c(12836, 12899, 12997, 13060, 13123, 13221, 13305, 13403, 13501, 13599), class = "Date"),
positive = c("yes", "no", "yes", "no", "yes", "no", "no", "yes", "yes", "yes")),
row.names = c(NA, 10L), class = "data.frame")
回答
您可以使用slider库进行此类滚动计算。语法解释 -
slide_index_lgl同时处理向量.x和索引.i并产生逻辑向量输出。.x用作positive向量.i用作date向量.before并且.after是不言自明的(包括前 365 天,不包括当天).f很简单,检查过去 365 天的测试阳性- 此输出与另一个条件相结合,即
positive == 'yes'我使用了这个公式(sum(.x == 'yes') / length(.x)) >= 0.5 - 1 被添加到这个逻辑输出,给我们
1forFALSE和2forTRUE - 此完整输出用作输出向量的索引
c('No', 'Yes') so that you'll getYesforTRUEandNoforFALSE`
library(tidyverse)
df <- read.table(header = TRUE, text = 'date positive
2005-02-22 yes
2005-04-26 no
2005-08-02 yes
2005-10-04 no
2005-12-06 yes
2006-03-14 no
2006-06-06 no
2006-09-12 yes
2006-12-19 yes
2007-03-27 yes')
df$date <- as.Date(df$date)
library(slider)
library(lubridate)
df %>%
mutate(chronic = c('No', "Yes")[1 + (positive == 'yes' & slide_index_lgl(positive, date,
~ (sum(.x == 'yes') / length(.x)) >= 0.5 ,
.before = days(365),
.after = days(-1)))])
#> date positive chronic
#> 1 2005-02-22 yes <NA>
#> 2 2005-04-26 no No
#> 3 2005-08-02 yes Yes
#> 4 2005-10-04 no No
#> 5 2005-12-06 yes Yes
#> 6 2006-03-14 no No
#> 7 2006-06-06 no No
#> 8 2006-09-12 yes No
#> 9 2006-12-19 yes No
#> 10 2007-03-27 yes Yes
runner::runner()在 baseR 中使用的替代策略
dat <- structure(list(date = structure(c(12836, 12899, 12997, 13060, 13123, 13221, 13305, 13403, 13501, 13599), class = "Date"),
positive = c("yes", "no", "yes", "no", "yes", "no", "no", "yes", "yes", "yes")),
row.names = c(NA, 10L), class = "data.frame")
library(runner)
dat$chronic <- ifelse(runner(dat$positive, idx = dat$date, lag = '1 day',
k = '365 days',
f = (.x) (sum(.x == 'yes')/length(.x)) >= 0.5) & dat$positive == 'yes', 'yes', 'no')
dat
#> date positive chronic
#> 1 2005-02-22 yes <NA>
#> 2 2005-04-26 no no
#> 3 2005-08-02 yes yes
#> 4 2005-10-04 no no
#> 5 2005-12-06 yes yes
#> 6 2006-03-14 no no
#> 7 2006-06-06 no no
#> 8 2006-09-12 yes no
#> 9 2006-12-19 yes no
#> 10 2007-03-27 yes yes