7

data.table を使用して、グループごとにいくつかの変数の加重合計を計算するソリューションを探しています。例が十分に明確であることを願っています。

require(data.table)

dt <- data.table(matrix(1:200, nrow = 10))
dt[, gr := c(rep(1,5), rep(2,5))]
dt[, w := 2]

# Error: object 'w' not found
dt[, lapply(.SD, function(x) sum(x * w)),
   .SDcols = paste0("V", 1:4)]

# Error: object 'w' not found
dt[, lapply(.SD * w, sum),
   .SDcols = paste0("V", 1:4)]

# This works with out groups
dt[, lapply(.SD, function(x) sum(x * dt$w)),
   .SDcols = paste0("V", 1:4)]

# It does not work by groups
dt[, lapply(.SD, function(x) sum(x * dt$w)),
   .SDcols = paste0("V", 1:4), keyby = gr]

# The result to be expected
dt[, list(V1 = sum(V1 * w),
          V2 = sum(V2 * w),
          V3 = sum(V3 * w),
          V4 = sum(V4 * w)), keyby = gr]

### from Aruns answer
dt[, lapply(.SD[, paste0("V", 1:4), with = F],
            function(x) sum(x*w)), by=gr]
4

1 に答える 1

6

最後の試み(ローランドの答えをコピーする:))

@Rolandの優れた回答をコピーする:

print(dt[, lapply(.SD, function(x, w) sum(x*w), w=w), by=gr][, w := NULL])

まだ最も効率的なものではありません: (2 回目の試行)

@Rolandのコメントに従って、すべての列で操作を実行してから、不要な列を削除する方が実際には高速です(操作自体に時間がかからない限り、ここではそうです)。

dt[, {lapply(.SD, function(x) sum(x*w))}, by=gr][, w := NULL][]

なんらかの理由で、w使用しないと見つからないよう{}です..理由はわかりませんが。


古い(非効率的な)答え:

(グループが多すぎると、サブセット化にコストがかかる可能性があります)

次のよう.SDcolsに提供する際に、使用したり削除したりせずにこれを行うことができます。lapply

dt[, lapply(.SD[, -1, with=FALSE], function(x) sum(x*w)), by=gr]
#    gr V1  V2  V3  V4
# 1:  1 20 120 220 320
# 2:  2 70 170 270 370

.SDcols.SD 柱なしで作りwます。wそのため、.SD環境の範囲内に存在しないため、乗算することはできません。

于 2013-07-19T10:33:49.230 に答える