2016-07-27 58 views
0

使用data.table日期时,我对访问和身份证上的日期数据:效率排名中的R

n  <- 1e6 
set.seed(42L) 
DT <- data.table(id = sample(1:37000, n, replace=TRUE), 
       date = as.Date("1963-07-13", "%Y-%m-%d") 
       - sample(1:9000, n, replace=TRUE)) 

我补充说,排名为每个人的访问的变量。访问#1,#2等。如果我无法区分两次访问,他们可以以任何(一致)方式排列。

经过我最后的question(效率)我意识到我应该学会如何使用data.table。所以我现在的解决方案是使用data.table - 唯一的问题是命令需要几秒钟才能运行。

> system.time(DT[, visit.n := rank(date, ties.method="first"), by = id] 
+) 
    user system elapsed 
    4.42 0.02 4.44 

我在想我是在做一些“错误的”,或者只是需要耐心等待。

+1

尝试'setkey(DT,date); system.time(DT [,visit.n:= 1:.N,by = id])' –

+2

假设你喜欢混乱的日期,你可以在i中使用order(date)来排序做新的col。如果你关心性能,你可能会考虑日期的整数存储格式,所以'system.time(DT [,date:= as.IDate(date)] [order(date),visit.n:= 1:.N ])'我看到这个花费的时间是Martin的setkey的一半。另请注意,该软件包的作者说:“因此,大多数情况下,不应该有必要再设置密钥。” http://stackoverflow.com/a/20057411/ – Frank

+1

有趣。但是你的代码行不会产生所需的输出,对吧?当添加'by = id'(所以输出是正确的)时,当'by = id'时,性能工作再次翻倍... –

回答

4

从我的评论摘自:

由于@Frank指出,setkey是没有必要的。只需使用order(date)就足以对日期进行排名。我还将他的日期保存为整数。

system.time({ 
    DT[, date := as.IDate(date)][order(date), visit.n := 1:.N, by=id] 
}) 

    user  system  elapsed 
    0.126  0.005  0.132 
+0

很大的改进!但我也尝试过'setkey(DT,id)',那更快。 – snoram

+0

正确,应用您的评论。 –

+1

setkey属于时间范围内; 1:.N现在在rowid(id)函数中可用;并且setkey很少是必需的(参见上面的注释)。只是fyi。哦,我猜Rowid仍然只在开发版本中。 – Frank