R语言数据框清理:规整输入与输出列的位置
清理混乱的R DataFrame:统一
.1结尾条目到V1列并匹配对应输出 先明确需求:把所有以.1结尾的标识(比如A.1、B.1)统一放到V1列,对应的成对输出(如abc&123)放到V2和V3列,无输出的标识对应位置填NA。
解决思路
核心是先提取所有.1结尾的标识,再逐个匹配它们对应的输出值:
- 把宽格式的混乱数据转成长格式,方便遍历所有条目
- 筛选出所有
.1结尾的标识,作为V1的完整列表 - 对每个标识,查找它之后的非
.1条目作为对应输出;如果后续紧跟的还是.1标识,说明该标识无输出,填NA
具体代码实现
用tidyverse工具包处理(未安装先运行install.packages("tidyverse")):
library(tidyverse) # 原始混乱数据 df <- data.frame(V1 = c("A.1", NA, "B.1", NA, "C.1", NA, NA, "E.1", NA, NA, NA, NA, NA, "H.1"), V2 = c(NA, "abc", NA, "def", NA, "D.1", "ghi", NA, "F.1", "C.1", "E.1", "G.1", "jkl", "mno"), V3 = c(NA, "123", NA, "456", NA, NA, "789", NA, NA, NA, NA, NA, "101", "112")) # 步骤1:转成长格式,保留行号和列信息 df_long <- df %>% mutate(row_num = row_number()) %>% pivot_longer(-row_num, names_to = "col", values_to = "value") %>% filter(!is.na(value)) %>% arrange(row_num, col) # 步骤2:标记所有.1结尾的条目,提取V1列表 df_long <- df_long %>% mutate(is_v1 = str_detect(value, "\\.1$")) %>% mutate(v1_id = cumsum(is_v1)) # 步骤3:分组匹配每个V1对应的V2和V3 df_clean <- df_long %>% group_by(v1_id) %>% summarise( V1 = first(value[is_v1]), V2 = ifelse(sum(!is_v1) >=1, value[!is_v1][1], NA), V3 = ifelse(sum(!is_v1) >=2, value[!is_v1][2], NA) ) %>% select(-v1_id) # 查看结果 print(df_clean)
结果验证
运行后得到的df_clean和目标结构完全一致:
V1 V2 V3 1 A.1 abc 123 2 B.1 def 456 3 C.1 <NA> <NA> 4 D.1 ghi 789 5 E.1 <NA> <NA> 6 F.1 <NA> <NA> 7 C.1 <NA> <NA> 8 E.1 <NA> <NA> 9 G.1 jkl 101 10 H.1 mno 112
补充说明
str_detect(value, "\\.1$")精准匹配以.1结尾的字符串,避免误匹配其他含.1的内容- 转长格式后按行号排序,保证条目顺序和原始数据一致
- 分组后通过
sum(!is_v1)判断当前V1条目是否有对应输出,有则取前两个作为V2和V3,无则填NA
内容的提问来源于stack exchange,提问作者Jen
相关产品推荐
相关产品推荐

