我想我有一个新问题,尽我所能,我一直无法解决。我已经使用这个网站几个月来学习R并且能够解决我迄今为止所有的问题。我正在进行一项大型回顾性队列研究,让我们说我们的样本看起来像这样:
my.df <- data.frame(ID = sample(c(1,2,3), 10, replace = TRUE),
Date = seq(as.Date("2012-08-01"),
as.Date("2012-11-01"), 1)[sample(1:10, 10)],
ICD = c( 401.3, 401.3, 250.02, 250.02, 110.1,
110.1, 250.02, 250.02, 250.02,112.1))
我需要做的是在两次连续访问中选择具有特定诊断的ID(比方说250.02)。为了做到这一点,我使用了类似的代码:
my.df<-with(my.df, my.df[order(ID,(as.Date(Date))), ])
根据日期组织数据,然后按ID分组。我认为,我的下一步是编写循环函数或使用ddply编写函数来选择具有相同ICD代码的连续日期。第一个问题是我正在研究具有非常大的数据集的糟糕计算机,而且我担心循环功能将如此占用大量内存,计算机将会冻结或崩溃。第二个问题是到目前为止,我主要通过矢量化数据来完成工作,并且我的循环/函数编程技能最多也缺乏。关于如何有效地解决这个问题的任何建议将不胜感激。
答案 0 :(得分:3)
这是一种方法,使用data.table包:
require(data.table)
my.dt <- data.table(my.df)
setkey(my.dt,ID,Date)
my.dt[,any(rle(ICD)$lengths>=2),by=ID][V1==TRUE]$ID
setkey
按ID
排序数据,然后按Date
排序。 rle(x)$lengths
是每次连续运行的长度。 by
会在每个any(rle(ICD)$lengths>=2)
内检查条件 - ID
。下一组方括号 - [V1==TRUE]
- 对数据进行子集化。您可以运行每个部件以查看其工作原理:
my.dt[,any(rle(ICD)$lengths>=2),by=ID] # and...
my.dt[,any(rle(ICD)$lengths>=2),by=ID][V1==TRUE] # and...
my.dt[,any(rle(ICD)$lengths>=2),by=ID][V1==TRUE]$ID
这也可能有助于澄清正在发生的事情:
my.dt[,rle(ICD),by=ID]
编辑:要对数据进行分组,这可行:
my.dt[
my.dt[,{
r <- rle(ICD)$lengths
rep(r>1,r)
},by=ID]$V1
]
您也可以分段运行,看看它是如何工作的。
答案 1 :(得分:2)
这是你想要的吗?
library(plyr)
df2 <- arrange(my.df, ID, Date)
# keep ID:s with at least one run longer than 2
df3 <- ddply(.data = df2, .variables = .(ID), subset,
any(rle(ICD)$lengths > 1))
df3
# and possibly subset df3 further:
# for each ID and ICD in df3, keep only ICD:s with more than one registration
df4 <- ddply(.data = df3, .variables = .(ID, ICD), subset,
length(ICD) > 1)
df4
我认为@ Frank的data.table
建议在大型数据集上会更快。
答案 2 :(得分:0)
这是一种方式:
library(plyr)
my.df <- data.frame(ID=sample(c(1,2,3), 10, replace=TRUE),
Date=seq(as.Date("2012-08-01"),
as.Date("2012-11-01"), 1)[sample(1:10, 10)],
ICD=c(401.3, 401.3, 250.02, 250.02, 110.1,
110.1, 250.02, 250.02, 250.02,112.1))
aggregation.fn <- function(df) {
df <- arrange(df, Date)
n <- nrow(df)
df$consecutive.ICD.are.equal <- c(FALSE, df$ICD[2:n] == df$ICD[1:(n-1)])
return(df)
}
my.df <- ddply(my.df, .(ID), aggregation.fn)
然后你可以检查子集(my.df,consecutive.ICD.are.equal&amp; ICD == 250.02)。
如果您的数据集非常大,您可以使ddply并行运行。