按升序/降序快速sortingdata.table
我有一个约300万行和40列data.table。 我想按照下面的SQL模拟代码按照降序sorting这个表:
sort by ascending Year, ascending MemberID, descending Month
data.table中有一个等价的方法来做到这一点? 到目前为止,我必须将其分解成2个步骤:
setkey(X, Year, MemberID)
这是非常快的,只需要几秒钟。
X <- X[,.SD[order(-Month)],by=list(Year, MemberID)]
这一步需要更长的时间(5分钟)。
更新:有人发表评论做X <- X[sort(Year, MemberID, -Month)]
,后来被删除。 这种方法似乎要快得多:
user system elapsed 5.560 11.242 66.236
我的方法:setkey()然后命令(-Month)
user system elapsed 816.144 9.648 848.798
我现在的问题是:如果我想在Year,MemberId和Month(Year,MemberID,Month)之后进行总结,data.table是否能识别sorting顺序?
更新2:回应Matthew Dowle:
设置Year,MemberID和Month后,我仍然有多组logging。 我想要对每个组进行总结。 我的意思是:如果我使用X [order(Year,MemberID,Month)],求和是否利用data.table的二进制searchfunction:
monthly.X <- X[, lapply(.SD[], sum), by = list(Year, MemberID, Month)]
更新3:马修D提出了几种方法。 第一种方法的运行时间比order()方法快:
user system elapsed 7.910 7.750 53.916
马修:令我感到吃惊的是,大部分时间里,月份的标志转换。 没有它,setkey是快速的。
2014年6月5日更新:
data.table v1.9.3目前的开发版本实现了两个新的function,即: setorder
和setorderv
,它正是你所需要的。 这些函数通过引用对data.table
进行重新sorting,select每个列上的升序或降序来sorting。 退房?setorder
了解更多信息。
另外, DT[order(.)]
也默认优化为使用data.table
的内部快速顺序,而不是base:::order
。 与setorder
不同的setorder
,这将完成数据的整个拷贝,因此内存效率更低,但仍将比使用基本的订单快setorder
数量级。
基准:
下面是使用setorder
,data.table的内部快速命令和base:::order
的速度差异说明:
require(data.table) ## 1.9.3 set.seed(1L) DT <- data.table(Year = sample(1950:2000, 3e6, TRUE), memberID = sample(paste0("V", 1:1e4), 3e6, TRUE), month = sample(12, 3e6, TRUE)) ## using base:::order system.time(ans1 <- DT[base:::order(Year, memberID, -month)]) # user system elapsed # 76.909 0.262 81.266 ## optimised to use data.table's fast order system.time(ans2 <- DT[order(Year, memberID, -month)]) # user system elapsed # 0.985 0.030 1.027 ## reorders by reference system.time(setorder(DT, Year, memberID, -month)) # user system elapsed # 0.585 0.013 0.600 ## or alternatively ## setorderv(DT, c("Year", "memberID", "month"), c(1,1,-1)) ## are they equal? identical(ans2, DT) # [1] TRUE identical(ans1, ans2) # [1] TRUE
在这个数据上,基准表明data.table的顺序比base:::order
快大约79倍 , setorder
比base:::order
快135x 。
data.table
总是在C语言环境中sorting/sorting。 如果你需要在另一个地方订购,那么你需要使用DT[base:::order(.)]
。
所有这些新的优化和function一起构成FR#2405 。 bit64 :: integer64支持也被添加了 。
注意:请参阅历史logging/修订以获取更早的答案和更新。
评论是我的,所以我会发布答案。 我删除了它,因为我无法testing它是否与您已有的相同。 很高兴听到它更快。
X <- X[order(Year, MemberID, -Month)]
总结不应取决于您的行的顺序。