如何在R的DataFrame中对连续列批量执行最近两场比赛的5分钟归一化均值计算?
问题描述
我已经用以下代码实现了计算每位球员最近两场比赛的FGM(投篮命中数)的5分钟归一化均值:
df %>% arrange(game_date) %>% slice(tail(row_number(), 2), .by = PLAYER_NAME) %>% summarize(FGM = mean(FGM/MIN*5), .by = PLAYER_NAME)
现在需要把这个逻辑批量应用到DataFrame的连续列(比如示例中的FGA,实际数据包含更多列),要求通过列范围(如4:5)实现处理,并且保留原列名。
附测试DataFrame结构:
df<-structure(list(game_date = structure(c(19153, 19153, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19156, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159, 19159), class = "Date"), MIN = c(12.533, 10.067, 3.933, 32.847, 37.13, 4.72, 39.625, 34.983, 14.617, 1.317, 39.703, 42.533, 16.75, 44.05, 26.155, 1.317, 44.417, 21.413, 1.317, 30.237, 1.317, 14.287, 16.067, 1.317, 1.317, 4.683, 1.317, 1.317, 1.317, 1.017, 39.215, 39.918, 41.302, 41.817, 13.05, 1.05, 38.483, 43.682, 21.667, 44, 19.767, 40.21, 16.452, 1.05, 32.623, 17.782, 15.85, 1.017, 1.05, 7.95, 1.05), FGM = c(1, 0, 0, 3, 7, 0, 7, 3, 1, 0, 7, 12, 1, 5, 6, 0, 10, 0, 1, 4, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 6, 12, 5, 5, 2, 0, 4, 7, 0, 12, 2, 6, 1, 0, 4, 5, 1, 0, 0, 0, 0), FGA = c(2, 2, 0, 6, 22, 0, 14, 6, 3, 0, 15, 23, 2, 18, 8, 1, 20, 4, 1, 5, 0, 8, 2, 0, 1, 3, 1, 0, 0, 0, 8, 21, 20, 10, 3, 1, 12, 18, 2, 23, 6, 18, 6, 0, 8, 12, 2, 0, 0, 2, 0), PLAYER_NAME = c("Grant Williams", "Payton Pritchard", "Andre Iguodala", "Al Horford", "Stephen Curry", "Nemanja Bjelica", "Klay Thompson", "Draymond Green", "Otto Porter Jr.", "Nik Stauskas", "Marcus Smart", "Andrew Wiggins", "Kevon Looney", "Jaylen Brown", "Gary Payton II", "Damion Lee", "Jayson Tatum", "Derrick White", "Luke Kornet", "Robert Williams III", "Juan Toscano-Anderson", "Jordan Poole", "Grant Williams", "Juwan Morgan", "Aaron Nesmith", "Payton Pritchard", "Jonathan Kuminga", "Moses Moody", "Sam Hauser", "Andre Iguodala", "Al Horford", "Stephen Curry", "Klay Thompson", "Draymond Green", "Otto Porter Jr.", "Nik Stauskas", "Marcus Smart", "Andrew Wiggins", "Kevon Looney", "Jaylen Brown", "Gary Payton II", "Jayson Tatum", "Derrick White", "Luke Kornet", "Robert Williams III", "Jordan Poole", "Grant Williams", "Juwan Morgan", "Aaron Nesmith", "Payton Pritchard", "Sam Hauser")), row.names = c(NA, -51L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
可以用dplyr的across()函数批量处理指定范围的列,无需循环,代码简洁且保留原列名:
library(dplyr) df %>% arrange(game_date) %>% slice(tail(row_number(), 2), .by = PLAYER_NAME) %>% summarize( across(4:5, ~mean(.x/MIN*5)), # 4:5对应示例中的FGM和FGA列,替换为你的目标列范围 .by = PLAYER_NAME )
说明
across(4:5, ~mean(.x/MIN*5)):4:5是目标连续列的位置索引,.x代表当前遍历的列,对每一列执行(列值/MIN)*5的归一化后取均值。- 处理后自动保留原列名,同时按球员分组输出结果。
如果担心列索引变化出错,也可以直接用列名范围指定:
df %>% arrange(game_date) %>% slice(tail(row_number(), 2), .by = PLAYER_NAME) %>% summarize( across(FGM:FGA, ~mean(.x/MIN*5)), .by = PLAYER_NAME )
内容的提问来源于stack exchange,提问作者firmo23
相关产品推荐
相关产品推荐

