据我所知,如果R没有在for循环的范围内更新变量,那么我只是做了一些非常缓慢而昂贵的代码。不幸的是,在一系列非常紧迫的期限和C ++ / Java的强大背景下,这是我的首选行为,直到我可以开始我的R帽。
我有一个需要改进的功能。它需要一个数据帧(如下所示)返回唯一的 patid 值,并使用这些值来检索该数据帧的子集以进行日期修改。下面是一个修剪过的例子(注意,我刚从完成的运行中拉出来,所以日期已被修改)。我执行的最后一次R运行超过了2700万行的数据帧,大约需要四五个小时。数据框的大小会更大。
patid eventdate
1 12/03/1998
1 12/03/1998
2 04/03/2007
3 15/11/1980
3 15/11/1980
3 01/02/1981
功能的修剪示例:
rearrangeDates <- function(dataFrame) {
#return a list of the unique patient ids
uniquePatids <- getUniquePatidList(dataFrame) #this is only called once and is very fast
out=NULL
for(i in 1:length(uniquePatids)) { # iterate over the list
idf <- subset(dataFrame, dataFrame$patid=uniquePatids[[i]])
idf$eventdate <- as.POSIXct(idf$eventdate,format="%d/%m/%Y")
idf <- idf[order(idf$eventdate,decreasing=FALSE),]
out = rbind(out,idf)
}
return(out)
}
有人可以建议改进吗?
答案 0 :(得分:2)
由于您希望对patid
&amp; eventdate
这应该有用。
library(dplyr)
df %>%
mutate(eventdate = as.Date(eventdate, format="%d/%m/%Y")) %>%
arrange(patid, eventdate)
输出为:
patid eventdate
1 1 1998-03-12
2 1 1998-03-12
3 2 2007-03-04
4 3 1980-11-15
5 3 1980-11-15
6 3 1981-02-01
示例数据:
df <- structure(list(patid = c(1L, 1L, 2L, 3L, 3L, 3L), eventdate = c("12/03/1998",
"12/03/1998", "04/03/2007", "15/11/1980", "15/11/1980", "01/02/1981"
)), class = "data.frame", row.names = c(NA, -6L))
答案 1 :(得分:1)
这非常适合data.table
:您的数据有一个明确定义的键,您按(patid,eventdate)
进行分组,您知道输出df的大小将是&lt; =输入df的大小,这样可以安全地进行就地分配(更快),而不是追加,你不需要输出迭代附加,而data.table有一个很好的快速unique
功能。所以请试试下面的(无循环!)代码,让我们知道它与原始代码和dplyr
方法的比较:
require(data.table)
dt = data.table(patid=c(1,1,2,3,3,3), eventdate=c('12/03/1998','12/03/1998',
'04/03/2007', '15/11/1980', '15/11/1980','01/02/1981'))
dt[, eventdate := as.POSIXct(eventdate,format="%d/%m/%Y") ]
# If you set a key, the `by` operation will be super-fast
setkeyv(dt, c('patid','eventdate'))
odt <- dt[, by=.(patid,eventdate)]
patid eventdate
1: 1 1998-03-12
2: 1 1998-03-12
3: 2 2007-03-04
4: 3 1980-11-15
5: 3 1980-11-15
6: 3 1981-02-01
(最后一件事:不要害怕POSIXct / lt,尽早转换它们,它们比字符串效率更高,它们支持比较运算符,因此列可以用作键,排序在,比较。)
(对于最快的dplyr
实施,请使用dplyr::distinct()
)