根据两个连续日期选择变量

时间:2013-09-03 14:37:53

标签: r loops plyr

我想我有一个新问题,尽我所能,我一直无法解决。我已经使用这个网站几个月来学习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代码的连续日期。第一个问题是我正在研究具有非常大的数据集的糟糕计算机,而且我担心循环功能将如此占用大量内存,计算机将会冻结或崩溃。第二个问题是到目前为止,我主要通过矢量化数据来完成工作,并且我的循环/函数编程技能最多也缺乏。关于如何有效地解决这个问题的任何建议将不胜感激。

3 个答案:

答案 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

setkeyID排序数据,然后按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并行运行。

相关问题