1

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

4

3 回答 3

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,然后按Daterle(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
]

你也可以分段运行它,看看它是如何工作的。

于 2013-09-03T16:56:07.690 回答
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建议在大型数据集上会更快。

于 2013-09-03T17:14:24.627 回答
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, Continuous.ICD.are.equal & ICD == 250.02)。

如果您的数据集非常大,您可以让 ddply 并行运行。

于 2013-09-03T15:21:14.117 回答