如何为数据框中跨列重复的因子按顺序添加序号?
解决方案
方法1:使用tidyverse工具包
先加载tidyverse,通过长格式转换统一处理每个值的出现序号:
library(tidyverse) # 原始数据框 df <- data.frame(x = c("A", "B", "C"), y = c("D", "B", "E"), z = c("H", "A", "B")) # 转换处理 df1 <- df %>% rowid_to_column("row_num") %>% # 添加行号保证转宽后行顺序正确 pivot_longer(cols = -row_num, names_to = "col", values_to = "val") %>% # 转长格式 group_by(val) %>% # 按值分组 mutate(val_new = ifelse(row_number() == 1, val, paste0(val, row_number()))) %>% # 生成带序号的新值 ungroup() %>% pivot_wider(names_from = "col", values_from = "val_new") %>% # 转回宽格式 select(-row_num) # 移除行号列 # 查看结果 df1
运行后得到的df1就是目标格式:
x y z 1 A D H 2 B B1 A1 3 C E B2
方法2:Base R 实现
如果不想加载额外包,可以用基础R代码完成:
# 原始数据框 df <- data.frame(x = c("A", "B", "C"), y = c("D", "B", "E"), z = c("H", "A", "B")) # 把数据框转为向量,计算每个值的出现序号 vec <- unlist(df) counts <- ave(seq_along(vec), vec, FUN = seq_along) # 生成带序号的新向量 vec_new <- ifelse(counts == 1, vec, paste0(vec, counts)) # 转回数据框 df1 <- as.data.frame(matrix(vec_new, nrow = nrow(df), byrow = FALSE, dimnames = dimnames(df)))
逻辑说明
两种方法核心逻辑一致:
- 先追踪每个值在全局范围内的出现顺序(按列优先的遍历顺序);
- 第一次出现的值保留原字符,后续出现的在末尾追加其出现的序号;
- 最后将处理后的数据恢复为原数据框的结构。
内容的提问来源于stack exchange,提问作者divjakomorca
相关产品推荐
相关产品推荐

