我正在计算dplyr::summarize
销售数据的数据框。我进行分组(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()
)。
关于我的代码习惯的两个问题:
使用 summarise 是否比 更好
dplyr::filter
,因为 filter 会物理删除行,所以我必须将结果分配给df.tmp
然后将其左连接回原始 df (如下所示)?此外,在每行汇总计算中重复的大子集表达式使代码更难阅读。我是否应该担心(或不)缓存子集操作的行或逻辑索引,在一般情况下我可能会计算说 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)