为数据框每行计算条件聚合并新增列:mapply代码报错求助
问题排查:用mapply计算NBA球队累计胜场失败的原因
你想用mapply替代循环为数据框每行计算截至当前比赛日的球队赛季累计胜场,但代码报错,问题出在这几个地方:
1. mapply的参数使用错误
mapply不支持MARGIN参数,这个参数是apply/lapply等函数的专属,你写的MARGIN = 1属于无效参数。- 错误地将整个
game_data传给X参数,mapply是多参数映射工具,应该直接把需要的三个字段(赛季、日期、球队ID)作为独立参数传入,而非整个数据框。 - 代码里混用了
game_data和df两个变量:函数内用game_data做筛选,但mapply里传的是df的列,若df不是game_data的别名,会导致数据不匹配或变量未定义报错。
2. 函数返回值处理不当
你的函数返回的是一个tibble/数据框,但mapply默认会简化结果结构,当返回空数据框(无匹配记录)或数据框时,无法直接赋值为数据框的列。而且原函数没有处理无匹配数据的情况,会导致赋值失败。
修正后的mapply写法
如果一定要用mapply,可以调整如下:
# 统一变量名,避免混用 wins_up_to_function <- function(curr_season, curr_date, curr_teamId) { # 直接提取数值,而非返回数据框 res <- game_data %>% filter(season == curr_season, game_date < curr_date, team_id == curr_teamId) %>% summarize(x = sum(wl == "W", na.rm = TRUE)) %>% pull(x) # 无匹配数据时返回0 if (length(res) == 0) 0 else res } # 直接传递三个字段的向量给mapply game_data$w_tot <- mapply(wins_up_to_function, curr_season = game_data$season, curr_date = game_data$game_date, curr_teamId = game_data$team_id)
更高效的替代方案(推荐)
逐行循环或mapply的效率都不高,用dplyr的窗口函数可以实现向量级运算,速度快得多:
game_data <- game_data %>% # 按赛季、球队、比赛日期排序 arrange(season, team_id, game_date) %>% # 按赛季+球队分组 group_by(season, team_id) %>% # 计算截至当前比赛前的累计胜场:cumsum包含当前场,减去当前场的胜场结果 mutate(w_tot = cumsum(wl == "W") - (wl == "W")) %>% # 取消分组(可选) ungroup()
内容的提问来源于stack exchange,提问作者TeeseCaprice
相关产品推荐
相关产品推荐

