首页 文章

重新排序data.table记录的子集

提问于
浏览
1

假设我有以下data.table:

set.seed(123)
dt <- data.table (id=1:10,
                  group=sample(LETTERS[1:3], 10, replace=TRUE),
                  val=sample(1:100, 10, replace=TRUE),
                  ltr=sample(letters, 10),
                  col5=sample(100:200, 10)
                  )
setkey(dt, id)
(dt)
#     id group  val  ltr col5
#  1:  1     A   96    x  197
#  2:  2     C   46    r  190
#  3:  3     B   68    p  168
#  4:  4     C   58    w  177
#  5:  5     C   11    o  102
#  6:  6     A   90    v  145
#  7:  7     B   25    k  172
#  8:  8     C    5    l  120
#  9:  9     B   33    f  129
# 10: 10     B   96    c  121

现在我想通过 group 与分组处理它,每一组中,我需要通过 val 列订购记录,然后做每一有序组内的一些操作(例如,从 ltr 值添加一列以合并):

#     id group val ltr letters
#  1   6     A  90   v     v_x
#  2   1     A  96   x     v_x
#  3   7     B  25   k k_f_p_c
#  4   9     B  33   f k_f_p_c
#  5   3     B  68   p k_f_p_c
#  6  10     B  96   c k_f_p_c
#  7   8     C   5   l l_o_r_w
#  8   5     C  11   o l_o_r_w
#  9   2     C  46   r l_o_r_w
#  10  4     C  58   w l_o_r_w

(在此示例中,整个表已订购,但这不是必需的)

这就是我想象的代码:

dt1 <- dt[,
          {
            # processing here, reorder somehow
            # ???
            # ...
            list(id=id, ltr=ltr, letters=paste0(ltr,collapse="_"))
          },
          by=group]

提前感谢任何想法!

UPD . 如答案中所述,对于我的例子,我可以简单地按 group 然后按 val 进行排序 . 如果我需要做几个不同的排序?例如,我想按 col5 排序并添加 col5diff 列,它将显示 col5 值的差异:

#    id group val ltr col5 letters col5diff
# 1:  6     A  90   v  145     v_x        
# 2:  1     A  96   x  197     v_x       52
# 3: 10     B  96   c  121 k_f_p_c        
# 4:  9     B  33   f  129 k_f_p_c        8
# 5:  3     B  68   p  168 k_f_p_c       47
# 6:  7     B  25   k  172 k_f_p_c       51
# 7:  5     C  11   o  102 l_o_r_w        
# 8:  8     C   5   l  120 l_o_r_w       18
# 9:  4     C  58   w  177 l_o_r_w       75
#10:  2     C  46   r  190 l_o_r_w       88

好的,对于这个例子, letterscol5diff 的计算是独立的,所以我可以简单地连续执行:

setkey(dt, "group", "val")
dt[, letters := paste(ltr, collapse="_"), by = group]

setkey(dt, "group", "col5")
dt<-dt[, col5diff:={
  diff <- NA;
  for (i in 2:length(col5)) {diff <- c(diff, col5[i]-col5[1]);}
  diff; # updated to use := instead of list - thanks to comment of @Frank
}, by = group]

但如果我需要同时使用这两个排序(单个 {} 块),我也很高兴知道该怎么做 .

2 回答

  • 1

    除非我遗漏了某些内容,否则这只需要将 data.tablekey 设置为 groupval

    setkey(dt, "group", "val")
    #     id group val ltr col5
    #  1:  6     A  90   v  145
    #  2:  1     A  96   x  197
    #  3:  7     B  25   k  172
    #  4:  9     B  33   f  129
    #  5:  3     B  68   p  168
    #  6: 10     B  96   c  121
    #  7:  8     C   5   l  120
    #  8:  5     C  11   o  102
    #  9:  2     C  46   r  190
    # 10:  4     C  58   w  177
    

    您会看到值是自动排序的 . 现在您可以通过 group 进行子集化:

    dt[, letters := paste(ltr, collapse="_"), by = group]
    #     id group val ltr col5 letters
    #  1:  6     A  90   v  145     v_x
    #  2:  1     A  96   x  197     v_x
    #  3:  7     B  25   k  172 k_f_p_c
    #  4:  9     B  33   f  129 k_f_p_c
    #  5:  3     B  68   p  168 k_f_p_c
    #  6: 10     B  96   c  121 k_f_p_c
    #  7:  8     C   5   l  120 l_o_r_w
    #  8:  5     C  11   o  102 l_o_r_w
    #  9:  2     C  46   r  190 l_o_r_w
    # 10:  4     C  58   w  177 l_o_r_w
    
  • 2

    我想你只是在寻找 order

    dt[, letters:=paste(ltr[order(val)], collapse="_"), by=group]
    dt[order(group, val)]
    #    id group val ltr col5 letters
    # 1:  6     A  90   v  145     v_x
    # 2:  1     A  96   x  197     v_x
    # 3:  7     B  25   k  172 k_f_p_c
    # 4:  9     B  33   f  129 k_f_p_c
    # 5:  3     B  68   p  168 k_f_p_c
    # 6: 10     B  96   c  121 k_f_p_c
    # 7:  8     C   5   l  120 l_o_r_w
    # 8:  5     C  11   o  102 l_o_r_w
    # 9:  2     C  46   r  190 l_o_r_w
    #10:  4     C  58   w  177 l_o_r_w
    

    或者,如果您不想按引用添加列:

    dt[, list(id, val, ltr, letters=paste(ltr[order(val)], collapse="_")), 
         by=group][order(group, val)]
    #    group id val ltr letters
    # 1:     A  6  90   v     v_x
    # 2:     A  1  96   x     v_x
    # 3:     B  7  25   k k_f_p_c
    # 4:     B  9  33   f k_f_p_c
    # 5:     B  3  68   p k_f_p_c
    # 6:     B 10  96   c k_f_p_c
    # 7:     C  8   5   l l_o_r_w
    # 8:     C  5  11   o l_o_r_w
    # 9:     C  2  46   r l_o_r_w
    #10:     C  4  58   w l_o_r_w
    

相关问题