我有数据.表包含大约300万行和40列.我想在组内按降序对该表进行排序,如以下sql模拟代码:

sort by ascending Year, ascending MemberID, descending Month 

在数据中是否有一种等效的方法.桌子怎么做?到目前为止,我必须将其分解为两个步骤:

setkey(X, Year, MemberID)

这非常快,只需几秒钟.

X <- X[,.SD[order(-Month)],by=list(Year, MemberID)]

这一步需要更长的时间(5分钟).

更新:

user  system elapsed 
5.560  11.242  66.236 

我的方法:setkey()然后order(-Month)

   user  system elapsed 
816.144   9.648 848.798 

我现在的问题是:如果我想按年份、MemberId和排序后的月份(Year、MemberId、Month)进行汇总,则不需要数据.表识别排序顺序吗?

更新2:回复Matthew Dowle:

在设置了年份、成员ID和月份之后,每个组仍然有多个记录.我想 for each 小组总结一下.我的意思是:如果我使用X[order(Year,MemberID,Month)],那么求和是否利用了数据的二进制搜索功能.表:

monthly.X <- X[, lapply(.SD[], sum), by = list(Year, MemberID, Month)]

更新3:Matthew D提出了几种方法.第一种方法的运行时间比order()方法快:

   user  system elapsed 
  7.910   7.750  53.916 

马修:让我惊讶的是,转换月份符号花了大部分时间.没有它,setkey的速度很快.

推荐答案

2014年6月5日更新:

数据的当前开发版本.表v1.9.3实现了两个新功能,即:setordersetorderv,这正是您所需要的.这些函数可以对data.table by reference进行重新排序,并可以 Select 每列的升序或降序.查看?setorder了解更多信息.

此外,默认情况下,DT[order(.)]也被优化为使用data.tableinternal fast order而不是base:::order.与setorder不同的是,它将生成数据的整个副本,因此内存效率较低,但仍将比使用base的顺序操作快几个数量级.

基准:

这是一个使用setorder秒数据说明速度差异的例子.表的内部快速订单和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

根据这些数据,基准表明了这些数据.表的顺序是~79x fasterbase:::ordersetorderbase:::order.

data.table始终使用C语言环境进行排序/排序.如果您需要在另一个地区订购,只有这样您才需要使用DT[base:::order(.)].

所有这些新的优化和功能一起构成了FR #2405个.bit64::integer64 support also has been added


NOTE:请参考历史记录/修订,以获取早期答案和更新.

R相关问答推荐

返回句子中最长的偶数长单词

按自定义数字模式对变量名称排序

使用sensemakr和fixest feols模型(R)

如何在R中正确对齐放射状图中的文本

如何在ggplot 2线性图的每个方面显示每个组的误差条?

r中的stat_difference函数不起作用

用值序列对行进行子集化,并标识序列开始的列

par函数中的缩写,比如mgp,mar,mai是如何被破译的?

如何使用STAT_SUMMARY向ggplot2中的密度图添加垂直线

使用across,starts_with和ifelse语句变更多个变量

使用R中的正则表达式将一列分割为多列

根据类别合并(汇总)某些行

R中的哈密顿滤波

R Select()可以测试不存在的子集列

使用范围和单个数字将数字与字符串进行比较

ComplexHEAT:使用COLUMN_SPLIT时忽略COLUMN_ORDER

随机森林的带Shap值的蜂群图

调换行/列并将第一行(原始数据帧的第一列)提升为标题的Tidyr类似功能?

如何在使用箭头R包(箭头::OPEN_DATASSET)和dplyr谓词时编写具有整齐计算的函数?

有没有办法通过str_Detect()或其他字符串匹配函数来连接两个长度不等的数据帧?