R语言dplyr处理球员数据同姓合并异常、season_TOG对象找不到报错
问题原因说明
你的代码同时存在三个逻辑错误,才会触发数据错配、找不到对象的报错:
- 中间表赋值语句末尾残留多余的
%>%:管道符的作用是将左侧结果传递给右侧函数作为入参,末尾留空不接操作会导致生成的中间表带无效的分组/管道上下文,容易触发异常。 - 多表合并函数用法错误:基础包的
merge()一次仅支持合并2个数据框,你直接传入disp、games、TOG三个对象时,第三个位置的TOG不会被识别为待合并数据源,最终生成的表中根本不存在season_TOG字段,后续计算场均值时必然触发找不到对象的报错。 - 合并匹配键写法错误:当需要用多个字段作为合并匹配依据时,必须将列名组合为向量传给
by参数,你原代码的写法仅将player_first_name作为匹配键,同姓不同名的球员自然会被错误关联,最终生成带.x/.y后缀的重名字段。
另外你提到的拼接姓名生成唯一球员ID的需求,直接用paste(player_first_name, player_last_name, sep = " ")即可实现,不过你当前按姓、名两个字段分组/匹配的逻辑本身是可以实现唯一定位的,不需要额外拼接也能解决错配问题。
最优修正方案
你完全不需要拆分三个中间表再做合并,直接单次分组汇总就能算出所有需要的指标,从根源上避免多表匹配的错误,代码更简洁运行效率也更高:
library(dplyr) PropModel_df <- playerdata %>% group_by(player_first_name, player_last_name) %>% summarise( season_disposals = sum(disposals), season_game_count = n_distinct(match_round), season_TOG = sum(time_on_ground_percentage), avg_disp = season_disposals / season_game_count, avg_TOG = season_TOG / season_game_count, .groups = "drop" # 汇总完成后取消分组属性,避免后续操作异常 ) print(PropModel_df)
保留中间表的修正写法
如果你确实需要单独保留disp、games、TOG三个中间表,注意去掉每个赋值语句末尾多余的管道符,合并时使用dplyr系列的join函数,明确指定多列匹配键即可:
library(dplyr) # 生成中间表 disp <- playerdata %>% group_by(player_first_name, player_last_name)%>% summarise(season_disposals = sum(disposals), .groups = "drop") games <- playerdata %>% group_by(player_first_name, player_last_name) %>% summarise(season_game_count = n_distinct(match_round), .groups = "drop") TOG <- playerdata %>% group_by(player_first_name, player_last_name)%>% summarise(season_TOG = sum(time_on_ground_percentage), .groups = "drop") # 多表连表+计算衍生指标 PropModel_df <- disp %>% left_join(games, by = c("player_first_name", "player_last_name")) %>% left_join(TOG, by = c("player_first_name", "player_last_name")) %>% mutate( avg_disp = season_disposals/season_game_count, avg_TOG = season_TOG/season_game_count ) print(PropModel_df)
如果需要生成单独的全名唯一标识字段,在管道开头加一行mutate(player_full_name = paste(player_first_name, player_last_name, sep = " "))即可,后续分组、合并都可以直接用player_full_name作为匹配键。
内容的提问来源于stack exchange,提问作者DTJB214
相关产品推荐
相关产品推荐

