dplyr::summarize
販売データのデータフレーム全体を計算しています。group-by (S,D,Y) を実行し、各グループ内で 5..43 週の中央値と平均を計算し、それらを親 df にマージします。変数 X は売上です。X が NA になることはありません (つまり、df のどこにも明示的な NA はありません) が、その S、D、Y および週のセットにデータがない場合 (売上がない場合など)、それらの値を持つ行はありません。 dfで(その特定のパラメータセットの売上がゼロであることを意味すると考えてください)。言い換えれば、構造的に欠落している行に X=0 を代入します (ただしmelt/cast
、肥大化を避けるために、元の dfが必要ないことを願っています。 cast(fill....,add.missing=T)
orと同様caret::preProcess()
です)。
私のコードイディオムに関する2つの質問:
dplyr::filter
filter は行を物理的に削除するため、結果を割り当ててからdf.tmp
元の df に左結合する必要があるため (以下のように)、summaryよりも使用する方がよいでしょうか? また、要約計算のすべての行で繰り返される大きなサブセット式により、コードが読みにくくなります。n=20 の新しい集計変数を計算する一般的なケースでは、サブセット化操作の行または論理インデックスのキャッシュについて心配する必要がありますか (または心配しないでください)。S、D、Y グループとフィルターのすべての組み合わせ (それらの週) に行があるわけではないため、欠落している行の NA を置き換えるために集計を取得するにはどうすればよいでしょうか? 現在、私は以下のようにしています。
コードとデータセットの両方がプロプライエタリで申し訳ありませんが、コードのイディオムは次のとおりです。以下は、サンプル データを生成するために最初に実行する必要があるコードです。
# Compute median, mean of X across wks 5..43, for that set of S,D,Y-values
# Issue a) filter() or repeatedly use subset() within each calculation?
df.tmp <- df %.% group_by(S,D,Y) %.% filter(Week>=5 & Week<=43) %.%
summarize(ysd_med543_X = median(X),
ysd_mean543_X = mean(X)
) %.% ungroup()
# Issue b) how to replace NAs in groups where the group_by-and-filter gave empty output?
# can you merge this code with the summarize above?
df <- left_join(df, df.tmp, copy=F)
newcols <- match(c('ysd_mean543_X','ysd_med543_X'), names(df))
df[!complete.cases(df[,newcols]), newcols] <- c(0.0,0.0)
これを最初に実行して、サンプルデータを生成します。
set.seed(1234)
rep_vector <- function(vv, n) {
unlist(as.vector(lapply(vv, function(...) {rep(...,n)} )))
}
n=7
m=3
df = data.frame(S = rep_vector(10:12, n), D = 20:26,
Y = rep_vector(2005:2007, n),
Week = round(52*runif(m*n)),
X = 4e4*runif(m*n) + 1e4 )
# Now drop some rows, to model structurally missing rows
I <- sort(sample(1:nrow(df),0.6*nrow(df)))
df = df[I,]
require(dplyr)