我有大量数据,其中包含许多个体的病理测试数据。我提供了一个按比例缩小的数据集来描述案例类型。
library(plyr)
library(tidyr)
library(dplyr)
library(lubridate)
options(stringsAsFactors = FALSE)
dat <- structure(list(PersID = c("am1", "am2", "am2", "am3", "am3", "am4", "am4", "am4", "am4", "am4", "am4"), Sex = c("M", "F","F", "M", "M", "F", "F", "F", "F", "F", "F"), DateTested = c("21/10/2015", "9/07/2010", "24/09/2010", "23/10/2013", "25/10/2013", "28/04/2010", "23/06/2010", "21/07/2010", "20/10/2010", "4/03/2011", "2/12/2011"), Res = c("NR", "R", "R", "NR", "R", "R", "R", "R", "R", "R", "R"), Status = c("Yes", "No", "No", "Yes", "Yes", "No", "No", "No", "No", "No", "No"), DateOrder = c(1L, 1L, 2L, 1L, 2L, 1L, 2L, 3L, 4L, 5L, 6L)), .Names = c("PersID", "Sex", "DateTested", "Res", "Status", "DateOrder"), class = "data.frame", row.names = c(NA, -11L))
该数据描述了三种类型的人(1)仅具有单一结果的人(2)具有 2 个结果的人以及(3)具有多个结果的人。
我的目标是提出一个脚本,该脚本仅包含根据一组标准的个人行。从技术上讲,这是一种仅对后续结果在指定的再感染期(30 天)内的个体进行行计数的方法。
我已将数据转换为列表,并向其传递了许多函数以开始处理数据。
dat$DateTested <- dmy(dat$DateTested)
datList <- dlply(.data=dat, .variables=c('PersID'))
到目前为止我所做的是:
选择每人只有一个结果的所有行
fnSingleTests <- function(y){
y <- y[length(y$DateOrder)==1,]
}
singleTests <- ldply(datList, fnSingleTests, .id = NULL)
将数据框转换为列表并传递一个函数
确定 (a) 30 天内每人是否有两行
再感染期,则选择第一个,(b)如果有
每人两行以上,最后一条记录和第一条记录
记录在30天内,只保留第一个。
fnMultiTests <- function(y){
y <- y[length(y$DateOrder) > 1,]
}
multiTests <- llply(datList, fnMultiTests)
fnMultiTestsSplit <- function(y){
test <- difftime(y$DateTested[length(y$DateTested)], y$DateTested[1], units='days')
if (nrow(y) <=2){
if (test < 31){
y <- y[y$DateOrder == 1, ]
y <- y[!is.na(y$PerdID), ]
} else {
y <- y[y$DateOrder %in% 1:2, ]
y <- y[!is.na(y$PersID), ]
}
} else {
if (test < 31){
y <- y[y$DateOrder == 1, ]
y <- y[!is.na(y$PersID), ]
} else {
break()
}
}
}
finalTests <- ldply(multiTests, failwith(NULL, fnMultiTestsSplit, quiet = TRUE), .id = NULL)
然后我可以将数据帧与 rbind 结合起来:
allFinalTests <- rbind(singleTests, finalTests)
我遇到困难的是每人超过两行的情况,并且在连续的行中可能存在一段时间大于 30 天的再感染期的情况。
任何人都可以建议我如何扩展此代码以仅包含两个以上的情况PersID
然后仅包含在 30 天再感染期之外发生后续病例的结果。
具体来说,从最旧的案例开始,如果下一个案例在 30 天内,则排除第二个案例,或者如果第二个案例距离前一个案例超过 30 天,则包括这两个案例。它应该对相同的所有情况执行此操作PersID
在此示例中,我要查找的最终输出是:
PersID Sex DateTested Res Status DateOrder
am1 M 21/10/2015 NR Yes 1
am2 F 9/07/2010 R No 1
am2 F 24/09/2010 R No 2
am3 M 23/10/2013 NR Yes 1
am4 F 28/04/2010 R No 1
am4 F 23/06/2010 R No 2
am4 F 20/10/2010 R No 4
am4 F 4/03/2011 R No 5
am4 F 2/12/2011 R No 6