如何在R数据集中按规则自动为测量记录分配访视编号?
基础需求:按连续3条记录分配访视号
针对每条记录对应单个测量值的场景,每3条连续记录归为同一访视号,剩余不足3条的记录标记为NA,可以用基础R代码快速实现:
DF <- data.frame(ID = rep("ID01", 10), M = 1:10) # 计算完整的3条记录组数量 full_groups <- floor(nrow(DF)/3) # 生成访视号,超出完整组的记录设为NA DF$V <- ifelse(seq_along(DF$M) <= full_groups*3, ceiling(seq_along(DF$M)/3), NA)
运行后DF$V结果为c(1,1,1,2,2,2,3,3,3,NA),与期望一致。
更新需求:按测量值M的水平分配访视号(子记录长度不固定)
当每个测量值M对应多条子记录,且M各水平的子记录长度不固定时,核心思路是先给M的唯一水平分配访视号,再将访视号批量映射到所有子记录上,以下提供两种实现方式:
方法1:基础R实现
set.seed(123) # 固定随机数便于复现 DF <- data.frame(ID = rep("ID01", 50), M0 = sample(50), M = rep(1:10, each = 5)) # 提取M的唯一水平并分配访视号 unique_M <- unique(DF$M) full_m_groups <- floor(length(unique_M)/3) m_v_map <- data.frame( M = unique_M, V = ifelse(seq_along(unique_M) <= full_m_groups*3, ceiling(seq_along(unique_M)/3), NA) ) # 将访视号映射回原数据集 DF$V <- m_v_map$V[match(DF$M, m_v_map$M)]
方法2:dplyr包实现(更简洁)
适合处理大型数据集,无需额外创建映射表:
library(dplyr) set.seed(123) DF <- data.frame(ID = rep("ID01", 50), M0 = sample(50), M = rep(1:10, each = 5)) DF <- DF %>% # 给每个M水平标记唯一序号 mutate(M_rank = dense_rank(M)) %>% # 分配访视号,超出完整组的M水平对应记录设为NA mutate(V = ifelse(M_rank <= floor(max(M_rank)/3)*3, ceiling(M_rank/3), NA)) %>% # 可选:删除中间生成的M_rank列 select(-M_rank)
验证子记录长度不固定的场景
构造M各水平子记录长度不同的数据集测试:
set.seed(123) DF <- data.frame( ID = rep("ID01", 21+26+18+15+10), M0 = sample(21+26+18+15+10), M = c(rep(1,21), rep(2,26), rep(3,18), rep(4,15), rep(5,10)) ) DF <- DF %>% mutate(M_rank = dense_rank(M)) %>% mutate(V = ifelse(M_rank <= floor(max(M_rank)/3)*3, ceiling(M_rank/3), NA)) %>% select(-M_rank)
此时M的前3个水平(1-3)对应访视号1-3,每个水平下的所有子记录都会带上对应访视号;M的4-5水平对应的所有子记录则标记为NA,完全符合需求。
内容的提问来源于stack exchange,提问作者Orangemarmalade
相关产品推荐
相关产品推荐

