R语言技术求助:查找data.frame中Type为B的行的前后Type为A的行
解决方案:提取Type为B的记录前后的Type为A的V1/V2字段
没问题,我来帮你搞定这个需求!下面分两种常见场景给出R代码实现,你可以根据实际情况选择:
场景1:提取紧邻B行的前一行/后一行中Type为A的记录
如果你的需求是仅当B的前一行(行号i-1)或后一行(行号i+1)恰好是Type=A时,才提取它们的V1和V2字段,用下面的代码:
基础R实现
# 先获取所有Type为B的行索引 b_indices <- which(df$Type == "B") # 遍历每个B行,检查前后行并提取数据 result_list <- lapply(b_indices, function(i) { # 处理前一行的A prev_a <- if (i > 1 && df$Type[i-1] == "A") { df[i-1, c("V1", "V2")] } else { NULL } # 处理后一行的A next_a <- if (i < nrow(df) && df$Type[i+1] == "A") { df[i+1, c("V1", "V2")] } else { NULL } # 整理成结构化数据,标记属于哪个B行 data.frame( B行号 = i, 来源 = c(rep("前一行_A", ifelse(is.null(prev_a), 0, 1)), rep("后一行_A", ifelse(is.null(next_a), 0, 1))), rbind(prev_a, next_a) ) }) # 合并结果为一个data.frame final_result <- do.call(rbind, result_list)
dplyr实现(更简洁的向量式操作)
如果你习惯用tidyverse工具包,这个方法更高效:
library(dplyr) final_result <- df %>% # 新增前后行的Type标记,以及当前行是否为B mutate( 前一行Type = lag(Type), 后一行Type = lead(Type), 是B行 = Type == "B" ) %>% # 只保留B行的记录 filter(是B行) %>% rowwise() %>% # 提取前后行的V1/V2(仅当对应行是A时) mutate( 前一行_A_V1 = if (前一行Type == "A") lag(V1) else NA, 前一行_A_V2 = if (前一行Type == "A") lag(V2) else NA, 后一行_A_V1 = if (后一行Type == "A") lead(V1) else NA, 后一行_A_V2 = if (后一行Type == "A") lead(V2) else NA ) %>% ungroup() %>% # 保留需要的列 select(B行号 = row_number(), 前一行_A_V1, 前一行_A_V2, 后一行_A_V1, 后一行_A_V2)
场景2:提取B行前后最近的Type为A的记录
如果你的需求是不管前后行是否紧邻,只要找到B行之前最近的一个A行,以及之后最近的一个A行(即使中间隔了其他类型的行),可以用下面的代码:
基础R实现
# 获取所有Type为A的行索引 a_indices <- which(df$Type == "A") b_indices <- which(df$Type == "B") result_list <- lapply(b_indices, function(i) { # 找到前面最近的A行索引 prev_a_idx <- max(a_indices[a_indices < i], na.rm = TRUE) prev_a <- if (!is.infinite(prev_a_idx)) df[prev_a_idx, c("V1", "V2")] else NULL # 找到后面最近的A行索引 next_a_idx <- min(a_indices[a_indices > i], na.rm = TRUE) next_a <- if (!is.infinite(next_a_idx)) df[next_a_idx, c("V1", "V2")] else NULL # 整理结果 data.frame( B行号 = i, 来源 = c(rep("最近前_A", ifelse(is.null(prev_a), 0, 1)), rep("最近后_A", ifelse(is.null(next_a), 0, 1))), rbind(prev_a, next_a) ) }) final_result <- do.call(rbind, result_list)
你可以把自己的df代入上面的代码,运行后就能得到你需要的结果啦!
内容的提问来源于stack exchange,提问作者jester
相关产品推荐
相关产品推荐

