5

この演習では、R の data.table を使用して要素を組み合わせて、値の数値ベクトルを集計します。次のデータ テーブルを例に取ります。

require (data.table)
require (plyr)
dtb <- data.table (cbind (expand.grid (month = rep (month.abb[1:3], each = 3),
                                       fac = letters[1:3]),
                          value = rnorm (27)))

「month」と「fac」の一意の組み合わせがすべて 3 回表示されることに注意してください。したがって、これらの両方の要因で値を平均しようとすると、9 つの一意の行を持つデータ フレームが期待されます。

(agg1 <- ddply (dtb, c ("month", "fac"), function (dfr) mean (dfr$value)))
  month fac          V1
1   Jan   a -0.36030953
2   Jan   b -0.58444588
3   Jan   c -0.15472876
4   Feb   a -0.05674483
5   Feb   b  0.26415972
6   Feb   c -1.62346772
7   Mar   a  0.24560510
8   Mar   b  0.82548140
9   Mar   c  0.18721114

ただし、data.table で集計すると、次の 2 つの要素の冗長な組み合わせごとに結果が得られます。

(agg2 <- dtb[, value := mean (value), by = list (month, fac)])
    month fac       value
 1:   Jan   a -0.36030953
 2:   Jan   a -0.36030953
 3:   Jan   a -0.36030953
 4:   Feb   a -0.05674483
 5:   Feb   a -0.05674483
 6:   Feb   a -0.05674483
 7:   Mar   a  0.24560510
 8:   Mar   a  0.24560510
 9:   Mar   a  0.24560510
10:   Jan   b -0.58444588
11:   Jan   b -0.58444588
12:   Jan   b -0.58444588
13:   Feb   b  0.26415972
14:   Feb   b  0.26415972
15:   Feb   b  0.26415972
16:   Mar   b  0.82548140
17:   Mar   b  0.82548140
18:   Mar   b  0.82548140
19:   Jan   c -0.15472876
20:   Jan   c -0.15472876
21:   Jan   c -0.15472876
22:   Feb   c -1.62346772
23:   Feb   c -1.62346772
24:   Feb   c -1.62346772
25:   Mar   c  0.18721114
26:   Mar   c  0.18721114
27:   Mar   c  0.18721114
    month fac       value

これらの結果をデータ テーブルとの要素の一意の組み合わせごとに 1 つの行に折りたたむエレガントな方法はありますか?

4

2 に答える 2

9

この問題 (および推論) は、集計された値が計算されただけでなく割り当てられているという事実に関連しています。

計算に使用されている列だけでなく、より多くの列を持つ data.table を見ると、これを実際に観察するのが簡単になります。

# Therefore, let's add a new column
dtb[, newCol := LETTERS[seq(length(value))]

計算された値を出力したいだけの場合は、そのままの式で問題ないことに注意してくださいRHS

# This gives the expected results
dtb[, mean (value), by = list (month, fac)]

# This on the other hand assigns the respective values to *each* row
dtb[, value := mean (value), by = list (month, fac)]

つまり、一意の値のみを返すようにデータがサブセット化されています。
ただし、この値をSAMEデータ テーブルに保存し直す場合 (これは、:=演算子を使用した場合に発生します)、で識別されるiすべての行 (既定ではすべての行) に値が割り当てられます。(追加の列で出力を見ると、これは理にかなっています)

次に、この data.table を agg にコピーしても、すべての行が送信されます。

したがって、新しいテーブルにコピーする場合は、元のテーブルから一意の行のみをコピーできます。

a.  wrap the original table inside `unique()` before assigning it
b.  assign the table, above, that is returned when you 
    are not assigning the RHS output (which is what @Arun suggested)

例はa.次のとおりです。

 agg2 <- unique(dtb[, value := mean (value), by = list (month, fac)])

次の例は、説明に役立つ場合があります。

(出力が省略されているため、これをコピーして貼り付ける必要があります)

  # SAMPLE DATA, as above
  library(data.table)
  dtb.bak <- data.table (expand.grid (month = rep (month.abb[1:3], each = 3), fac = letters[1:3]), value = rnorm (27))

  #  METHOD 1  # 
  #------------#
  dtb <- copy(dtb.bak)  # restore, from sample data.


  dtb[, value := mean (value), by = list (month, fac)]
  dtb

  # this is what you would like to assign
  unique(dtb)


  #  METHOD 2  # 
  #------------#
  dtb <- copy(dtb.bak)  # restore, from sample data.

  # this is what you would like to assign
  # next two lines are the same, only differnce is column name
  dtb[, mean (value), by = list (month, fac)]
  dtb[, list("mean" = mean (value)), by = list (month, fac)]  # quote marks added for clarity

  # dtb is unchanged. 
  dtb



  # NOW COMPARE THE SAME TWO METHODS, BUT IF THERE IS AN ADDITIOANL COLUMN
  dtb.bak[, newCol := rep(c("A", "B", "A"), length(value)/3)]


  dtb1 <- copy(dtb.bak)  # restore, from sample data.
  dtb2 <- copy(dtb.bak)  # restore, from sample data.


  # Method 1
  dtb1[, value := mean (value), by = list (month, fac)]
  dtb1
  unique(dtb1)

  #  METHOD 2  # 
  dtb2[, list("mean" = mean (value)), by = list (month, fac)]  # quote marks added for clarity
  dtb2

  # METHOD 2, WITH ADDED COLUMNS IN list() in `j`
  dtb2[, list("mean" = mean (value), newCol), by = list (month, fac)]  # quote marks added for clarity
  # notice this has more columns thatn 
  unique(dtb1)
于 2013-03-05T21:37:02.050 に答える
6

やったほうがいい:

agg2 <- dtb[, list(value = mean(value)), by = list (month, fac)]

:=RHSの要素数に合わせて の値をリサイクルしますLHS?':='これについてもっと読むために実行してください。

于 2013-03-05T19:08:39.783 に答える