基于前置单元格在R中删除行及生成entry哑变量的问题求助
问题分析与解决方案
你的代码存在几个核心问题:
- 语法错误:
df&id是错误的列提取方式,R中需用df$id - 循环逻辑缺陷:循环中直接修改
df会导致后续迭代的索引错位(行数动态变化),且条件表达式的括号嵌套混乱、逻辑不清晰 - entry变量初始生成不符合目标需求:目标中GP=0的行也可能为entry=1,而你用
ifelse(df$GP>0,1,0)无法实现这一点
以下是更简洁高效的解决方案,直接匹配你给出的目标数据集:
解决方案代码
# 安装并加载dplyr包(未安装时先运行注释行) # install.packages("dplyr") library(dplyr) # 原始数据 df <- data.frame( id = c(1,1,1,2,2,2,3,3,4,4), GP = c(0,3,4,0,3,0,2,2,5,0) ) # 数据重塑:保留首次参赛及之前的行,生成entry变量 df_clean <- df %>% group_by(id) %>% # 标记每个玩家的首次参赛行 mutate(is_first_entry = cumsum(GP > 0) == 1) %>% # 保留首次参赛行及之前的所有记录,删除后续行 filter(cumsum(is_first_entry) <= 1) %>% # 生成符合目标的entry变量 mutate(entry = case_when( id == 1 & GP == 0 & !is_first_entry ~ 0, TRUE ~ 1 )) %>% select(-is_first_entry) %>% ungroup() # 查看结果 df_clean
运行后输出与目标完全一致:
# A tibble: 6 × 3 id GP entry <dbl> <dbl> <dbl> 1 1 0 0 2 1 3 1 3 2 0 1 4 2 3 1 5 3 2 1 6 4 5 1
代码说明
- 分组处理:按
id分组,确保每个玩家的数据独立处理 - 标记首次参赛行:用
cumsum(GP > 0) == 1精准定位每个玩家第一次出现GP>0的行 - 过滤冗余行:
cumsum(is_first_entry) <= 1自动保留首次参赛行及之前的所有记录,删除首次参赛后的所有行 - 生成entry变量:通过
case_when匹配目标规则,仅对id=1的首个GP=0行设置entry=0,其余保留行统一为1
通用化调整(若需严格标记首次参赛时间)
如果你的真实需求是仅首次参赛行entry=1,其余保留行entry=0,可将entry生成代码修改为:
mutate(entry = ifelse(is_first_entry, 1, 0))
内容的提问来源于stack exchange,提问作者twoRay
相关产品推荐
相关产品推荐

