如何翻转含NA行的数据框中连续的yes与no行?
解决方案:翻转数据框中连续的yes/no行
问题背景
现有如下R数据框,需要将name列中每一组连续的yes和no两行顺序翻转:
df = data.frame(name = c('a','b','c',NA,NA,'yes','no',NA,NA,'f','g','h'), Freq = c(10,20,70,NA,NA,40,60,NA,NA,80,10,10) )
原数据输出:
name Freq 1 a 10 2 b 20 3 c 70 4 <NA> NA 5 <NA> NA 6 yes 40 7 no 60 8 <NA> NA 9 <NA> NA 10 f 80 11 g 10 12 h 10
目标输出:
name Freq 1 a 10 2 b 20 3 c 70 4 <NA> NA 5 <NA> NA 6 no 60 7 yes 40 8 <NA> NA 9 <NA> NA 10 f 80 11 g 10 12 h 10
方法1:dplyr分组处理(适合大规模/不规则数据)
自动识别所有连续的yes/no组,鲁棒性强:
library(dplyr) df_processed <- df %>% # 标记分组:将非yes/no的行、NA行作为分组分隔点 mutate(group = cumsum(!is.na(name) & !(name %in% c("yes", "no")) | is.na(name))) %>% group_by(group) %>% mutate( # 仅对纯yes/no的组反转行顺序,其他组保持原顺序 row_order = if(all(name %in% c("yes", "no"), na.rm = TRUE)) rev(row_number()) else row_number() ) %>% arrange(group, row_order) %>% # 清理辅助列 select(-group, -row_order) %>% ungroup() print(df_processed)
方法2:Base R实现(适合规则化成对数据)
假设yes/no总是连续成对出现,代码更轻量化:
# 定位所有yes/no行的索引 yes_no_idx <- which(df$name %in% c("yes", "no")) # 每两个索引分为一组 idx_groups <- split(yes_no_idx, ceiling(seq_along(yes_no_idx)/2)) # 遍历每组翻转行顺序 for(g in idx_groups){ if(length(g) == 2){ df[g, ] <- df[rev(g), ] } } print(df)
补充说明
- 方法1:无需假设数据规则,能处理单个yes/no或多个连续yes/no的情况,适合实际业务中数据可能存在的不规则场景。
- 方法2:依赖yes/no成对连续的前提,代码更简洁高效,适合数据格式固定的场景。
内容的提问来源于stack exchange,提问作者An116
相关产品推荐
相关产品推荐

