如何基于Y列值,按GameId/PlayId分组替换Position列的'T'/'G'为LT/RT/LG/RG?
解决方案:基于分组替换R语言data.frame中的Position值
针对批量处理需求,推荐使用dplyr或data.table包实现分组逻辑替换,两种方法都能高效处理数千行数据:
方法一:使用dplyr(语法直观易读)
先加载dplyr包,通过分组后判断Y值大小完成替换:
library(dplyr) # 示例输入数据 tracking_data <- data.frame( GameId = c("2017090700", "2017090700", "2017090700", "2017090700", "2017090700", "2017090700"), PlayId = c("20170907000118", "20170907000118", "20170907000118", "20170907000118", "20170907000118", "20170907000118"), Y = c(20.92333, 28.21333, 23.84333, 22.80333, 21.45333, 24.86333), Position = c("T", "T", "QB", "RB", "G", "G") ) # 批量处理逻辑 tracking_data_processed <- tracking_data %>% # 按GameId、PlayId、Position分组,确保同组内是同位置球员 group_by(GameId, PlayId, Position) %>% mutate( Position = case_when( # T位置:Y值最高的设为LT,其余为RT Position == "T" ~ ifelse(Y == max(Y), "LT", "RT"), # G位置:Y值最高的设为LG,其余为RG Position == "G" ~ ifelse(Y == max(Y), "LG", "RG"), # 其他位置保持原数值 TRUE ~ Position ) ) %>% ungroup() # 查看结果 print(tracking_data_processed)
输出结果与期望完全一致:
GameId PlayId Y Position 1 2017090700 20170907000118 20.92333 RT 2 2017090700 20170907000118 28.21333 LT 3 2017090700 20170907000118 23.84333 QB 4 2017090700 20170907000118 22.80333 RB 5 2017090700 20170907000118 21.45333 RG 6 2017090700 20170907000118 24.86333 LG
方法二:使用data.table(大数据集处理更高效)
若数据集规模极大,data.table的分组运算速度更具优势:
library(data.table) setDT(tracking_data) tracking_data_processed <- tracking_data[, Position := case_when( Position == "T" ~ ifelse(Y == max(Y), "LT", "RT"), Position == "G" ~ ifelse(Y == max(Y), "LG", "RG"), TRUE ~ Position ), by = .(GameId, PlayId, Position) ]
关键逻辑说明
- 分组维度:
GameId + PlayId + Position确保仅在同一场比赛、同一回合的同位置球员中比较Y值 - 替换规则:通过
max(Y)定位分组内Y值最高的记录,对应替换为"L开头"的位置,其余为"R开头"的位置 - 兼容性:两种方法均保留非T/G位置的原始值,不会影响其他数据
内容的提问来源于stack exchange,提问作者Loons22
相关产品推荐
相关产品推荐

