在R语言中删除与其他行相似的行的方法咨询
看起来你在处理棒球投球数据的清洗问题——按eventNum分组后,每组里大部分列数据重复,只有少数列(比如inning、pitchSeq)有差异,你想删掉每组里的“中间过程行”,只留代表最终结果的行对吧?下面给你几个通用的R解决方案,还能批量处理几百个文件:
方案1:保留每个eventNum组的最后一行(默认最后一行是最终结果)
如果每个事件的最后一条记录就是你需要保留的最终状态,用dplyr的分组取尾操作最直接:
首先加载必备工具包:
library(tidyverse)
处理单个文件的代码:
# 读取数据(如果是txt格式,换成read.table,参数按需调整) raw_data <- read_csv("your_input_file.csv") # 按eventNum+击球手分组(避免不同击球手的同eventNum被混在一起),保留每组最后一行 clean_data <- raw_data %>% group_by(eventNum, batter) %>% slice_tail(n = 1) %>% ungroup() # 保存清洗后的数据 write_csv(clean_data, "your_cleaned_file.csv")
批量处理多个文件的代码:
# 获取目标文件夹下所有csv文件的路径 file_list <- list.files(path = "your_data_folder", pattern = "\\.csv$", full.names = TRUE) # 定义批量清洗函数 clean_single_file <- function(file_path) { # 读取文件 data <- read_csv(file_path) # 清洗逻辑 cleaned_data <- data %>% group_by(eventNum, batter) %>% slice_tail(n = 1) %>% ungroup() # 生成输出文件名(原文件名后加_cleaned) output_name <- str_replace(file_path, "\\.csv$", "_cleaned.csv") # 保存 write_csv(cleaned_data, output_name) } # 遍历所有文件执行清洗 walk(file_list, clean_single_file)
方案2:保留每个eventNum组的最后N行(N可自定义)
如果需要保留每组的最后固定行数(比如你例子里想保留最后2行),只需修改slice_tail的参数:
clean_data <- raw_data %>% group_by(eventNum, batter) %>% slice_tail(n = 2) # 这里的2可以根据你的需求调整 ungroup()
要是需要根据组的大小动态调整保留行数(比如组内行数≤3时全留,否则留最后2行),可以这么写:
clean_data <- raw_data %>% group_by(eventNum, batter) %>% mutate(group_total_rows = n()) %>% slice_tail(n = ifelse(group_total_rows <= 3, group_total_rows, 2)) %>% select(-group_total_rows) %>% # 删掉临时计算的列 ungroup()
方案3:删除连续重复的投球类型行
如果你的“重复行”是指连续出现相同的pitchSeq,想只保留每个连续重复段的最后一行,用lag()函数判断过滤:
clean_data <- raw_data %>% group_by(eventNum, batter) %>% # 只保留和前一行投球类型不同的行(第一行默认保留) filter(pitchSeq != lag(pitchSeq, default = first(pitchSeq))) %>% ungroup()
这个方案会把每组里连续重复的投球记录合并,比如eventNum=50里的F→F→B→B→S会变成F→B→S三条记录。
方案4:按指定列去重(忽略inning等动态列)
如果你的“重复行”是指除了inning、pitchSeq之外的列完全相同,想保留每个唯一组合的最后一行,就把需要判断重复的列都放进group_by里:
clean_data <- raw_data %>% # 列出所有用来判断重复的列(比如outs、balls、strikes、batter这些不变的列) group_by(eventNum, outs, balls, strikes, batter) %>% slice_tail(n = 1) %>% ungroup()
你可以根据自己的实际需求挑对应的方案,批量处理的逻辑和方案1一致,只要把清洗部分替换成对应代码就行。
内容的提问来源于stack exchange,提问作者seth pottle
相关产品推荐
相关产品推荐

