基于多列排序Data.Table数据

5
考虑下面的一个data.table:

DT <- data.table(a=c(1,2,4,3,5), b=c(3:5,NA,2), c=c(2,1,NA,NA,3)) 
DT
   a  b  c
1: 1  3  2
2: 2  4  1
3: 4  5 NA
4: 3 NA NA
5: 5  2  3

我希望按照第三列和第一列的顺序对行进行排序。我可以使用以下方法:

DT[order(DT[,3],DT[,1])]

   a  b  c
1: 2  4  1
2: 1  3  2
3: 5  2  3
4: 3 NA NA
5: 4  5 NA

但是,如果DT有许多列,假设我想根据第1到第i列对它们进行排序,那么将它们写成这样并不高效:

DT[order(DT[,1], DT[,2], DT[,3], ... DT[,i])]

相反,我想提供列索引作为向量(见下文):

DT[order(DT[,c(1:i)])]

但是,它并没有按照我的期望工作,并输出了:
DT[order(DT[,c(3,1)])]

     a  b  c
 1:  2  4  1
 2: NA NA NA
 3:  1  3  2
 4: NA NA NA
 5:  5  2  3
 6: NA NA NA
 7: NA NA NA
 8: NA NA NA
 9:  4  5 NA
10:  3 NA NA

有什么建议可以解决这个问题吗?谢谢!

2
请参考这里的答案,使用setorderv函数进行排序:如何按多列对数据框进行排序?。例如,对于一系列的列,比如 cols <- names(iris)[2:4];可以使用 setorderv(iris, cols) 进行排序。 - Henrik
谢谢@Henrik!setorderv对我有用:col<-names(DT)[c(3,1)],然后setorderv(DT,col,c(1,1))。但是,它将NA值放在顶部。我们是否有选择决定它们最终会在顶部还是底部? - Mahmoud
你有没有花时间阅读 ?setorderv - Henrik
哦,我明白了!有一个选项可以说“na.last=TRUE”。谢谢@Henrik! - Mahmoud
1个回答

6

在指定 .SDcols 后,我们可以使用 do.callorder

DT[DT[,do.call(order, .SD), .SDcols = c(3, 1)]]
#   a  b  c
#1: 2  4  1
#2: 1  3  2
#3: 5  2  3
#4: 3 NA NA
#5: 4  5 NA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接