R中如何基于同玩家t-1行的数值创建条件计算新列pts_per_game
实现方法
下面给出3种不同场景的实现方案,都可以满足你的需求:
方案1:tidyverse/dplyr 最简实现(推荐)
适合日常使用,代码可读性最高,核心用分组+偏移函数实现:
# 加载依赖包,没有安装的话先运行 install.packages("dplyr") library(dplyr) df <- df %>% # 按球员分组 group_by(player) %>% # 组内按t值升序排序,保证偏移取到的是t-1的行 arrange(t, .by_group = TRUE) %>% # lag()取同组上一行的计算结果,t最小的行自动返回NA mutate(pts_per_game = lag(min_per_game / 36 * pts_per_36_min)) %>% # 取消分组,避免后续操作报错 ungroup()
方案2:Base R 实现(无需安装额外包)
适合不希望加载第三方包的场景:
# 先按球员和t值升序排序 df_sorted <- df[order(df$player, df$t), ] # 按球员分组计算,每组第一个值设为NA,后续取前一行的计算结果 df_sorted$pts_per_game <- ave( df_sorted$min_per_game / 36 * df_sorted$pts_per_36_min, df_sorted$player, FUN = function(x) c(NA, x[-length(x)]) ) # 恢复原始数据的行顺序 df <- df_sorted[rownames(df), ]
方案3:通用自连接实现(兼容t值不连续的场景)
如果你的数据中t值不是严格连续的,用自连接可以严格匹配t-1的行,不会出错:
library(dplyr) # 生成匹配辅助表,存储每个球员每个t对应的待计算值,以及要匹配的目标t值 prev_df <- df %>% mutate( match_t = t + 1, calc_val = min_per_game / 36 * pts_per_36_min ) %>% select(player, match_t, calc_val) # 左连接匹配,无匹配结果自动返回NA df <- df %>% left_join(prev_df, by = c("player" = "player", "t" = "match_t")) %>% rename(pts_per_game = calc_val)
内容的提问来源于stack exchange,提问作者ben_p_4370
相关产品推荐
相关产品推荐

