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]

アイデアをお寄せいただきありがとうございます。

アップデート。回答で述べたように、私の例では、 bygroupで、次に by で単純に注文できvalます。そして、いくつかの異なる注文を行う必要がある場合はどうなりますか? たとえば、値の違いを示す列を並べ替えてcol5追加したいとします。col5diffcol5

#    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

この例では、lettersとの計算col5diffは独立しているので、単純に連続して実行できます。

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]

{}しかし、これらの順序付けの両方を (1 つのブロックで) 使用する必要がある場合の対処方法も教えていただければ幸いです。

4

2 に答える 2

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
于 2013-05-11T21:10:43.763 に答える
1

何かが欠けていない限り、これには を と に設定するだけkeyです:data.tablegroupval

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
于 2013-05-11T21:56:48.837 に答える