【问题标题】:How to order a data.table in R based on multiple columns with ties?如何在 R 中基于多个有关系的列对 data.table 进行排序?
【发布时间】:2017-01-07 01:39:38
【问题描述】:

我对 data.table 还很陌生,并且有一个基本问题。我正在尝试根据这两列重新排序以下数据表。

library(data.table)
DT <- data.table(letter=c('a','a','a','a','b','b','c','d','d','d','d'),  
                 value =c(1,2,4,8,2,5,1,1,2,3,9))

        letter value
 1:      a     1
 2:      a     2
 3:      a     4
 4:      a     8
 5:      b     2
 6:      b     5
 7:      c     1
 8:      d     1
 9:      d     2
10:      d     3
11:      d     9

我想根据最低关联值对字母进行排序,如果它们相等,则应该比较下一个值(如果可用)等等。

这应该会产生以下结果:

    letter value
 1:      c     1
 2:      d     1
 3:      d     2
 4:      d     3
 5:      d     9
 6:      a     1
 7:      a     2
 8:      a     4
 9:      a     8
10:      b     2
11:      b     5

我尝试过DT[order(value), .SD, letter],它确实按值排序,但在最低关联值的情况下不考虑后续值。我觉得应该有一个简单的方法来做到这一点,但我找不到答案。谢谢。

【问题讨论】:

  • 所以您想先按“价值”排序,然后按字母排序? setorder(DT, value, -letter) 呢?
  • 不,我想获得最低值的字母,然后是该字母的所有其他值。然后移动到具有下一个最小值的字母并获取具有该字母的所有行。在平局的情况下,必须比较字母的后续值。抱歉,如果不清楚。

标签: r data.table


【解决方案1】:

我想根据最低关联值对字母进行排序,如果它们相等,则应该比较下一个值(如果可用)等等。

这不是那么简单。首先,我们需要填充数据,使c 的“第二”值再次为1;第三个;第四个:

n = max(DT[, .N, by=letter]$N)
oDT = DT[, .(rid = 1:n, v = c(value, rep(value[.N], n-.N))), by=letter]

那么,我认为我们需要一个递归函数来检查关系:

chk_ties = function(L, r, maxr = n){
    if (r == maxr) 
        L
    else
        oDT[letter %in% L & rid == r, {
            if (.N > 1L)
                chk_ties(letter, r + 1L)
            else
                letter
        }, keyby=v]$V1
}

chk_ties(unique(DT$letter), 1L)
# [1] "c" "d" "a" "b"

或者,我意识到我们可以使用递归函数代替递归函数:

setorderv(dcast(oDT, letter ~ rid), as.character(1:n))$letter
# [1] "c" "d" "a" "b"

最后,我们需要加入,正如@lmo 的回答:

DT[setorderv(dcast(oDT, letter ~ rid), as.character(1:n))$letter, on="letter"]
# or
DT[chk_ties(unique(DT$letter), 1L), on=.(letter)]

可以在这里写on=.(letter)on="letter"

【讨论】:

  • 一如既往的好答案!
  • @sandrjekk 很高兴听到这个消息。仅供参考,很高兴您使用更具说明性的示例更新了问题,但是对已经发布答案让他们知道的人(通过在他们的答案下发表评论)进行 ping 操作是礼貌的。反正我现在才评论lmo的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多