通过 sapply 维护 tapply 索引

Maintain tapply indices through sapply

使用 tapply 和 sapply,我正在尝试根据我使用 sapply 给 tapply 的多个(两个)索引计算计数的总和。问题是返回的矩阵丢失了我给 tapply 的列名。我最终使用 melt() 将矩阵变成 data.frame 以输入到 ggplot 中,并且必须以更手动的方式添加变量名称,但我希望它们仅通过两个 apply() 函数保留。当我只在 tapply() 中使用索引时, metric/variable 名称被保留,所以我很困惑为什么它们会丢失两个索引。

    Fc_desc. <- rep(c(rep("Local",10),rep("Collector",10),rep("Arterial",10)),2)
Year. <- c(rep(seq(2000,2008,2),12))
df.. <- data.frame(Fc_desc = Fc_desc., Year = Year., Tot_ped_fatal_cnt = sample(length(Year.)),Tot_ped_inj_lvl_a_cnt = sample(length(Year.)))
#Define metrics(columns) of interest
Metrics. <- c("Tot_ped_fatal_cnt", "Tot_ped_inj_lvl_a_cnt")
#Summarize into long data frame
Ped_FcSv.. <- melt(sapply(Metrics., function(x){tapply(df..[,x],list(df..$Year, df..$Fc_desc), sum,na.rm=T)}),varnames = c("Fc_desc","Year","Injury_Severity"), value.name = "Count")

我最初的解决方案是使用循环和列表

Metrics. <- c("Tot_ped_fatal_cnt", "Tot_ped_inj_lvl_a_cnt")
TempList_ <- list()
for(metric in Metrics.){
    TempList_[[metric]] <- tapply(df..[,metric],list(df..$Year, df..$Fc_desc),      
       sum) 
}
TempList_YrSv <- melt(TempList_, varnames = c("Year","Fc_desc"), value.name = 
    "Count")
colnames(TempList_YrSv )[3] <- "Injury_Severity"

这使用 6 行,在我的 717,000 行实际数据上花费 0.46 秒

我修改并应用了Aosmith解决方案:

Cols. <- c(Metrics., "Year","Fc_desc")
#Transpose data to long form
df_long <- melt(df..[,Cols.], measure.vars = Metrics., variable.name = c("Injury_Severity"), value.name = "Count")
#Apply aggregate() to sum Count on 3 indices
Ped_YrSv.. <- aggregate(Count ~ Fc_desc + Year + Injury_Severity, data = df_long, FUN = sum,na.rm=T)

这个解决方案需要 3.9 秒,但只有 3 行。我意识到头发会分裂,但我正在努力变得更优雅并摆脱列表和循环,所以这很有帮助。我想我可以对此感到满意。谢谢大家