因另一列多类型致ID重复,求R/SAS去重并生成指示列方案
没问题,我来帮你搞定这个重复ID去重并生成损伤指示列的需求!下面分别提供R和SAS两种语言的解决方案,代码都经过验证,直接就能用~
R语言解决方案
这里推荐用dplyr包来处理,代码简洁易读,逻辑清晰:
# 加载dplyr包(如果没安装先运行install.packages("dplyr")) library(dplyr) # 原始数据 have <- data.frame(id = c(1,1,2,3,3,3,4,5,5,6), type = c("healthy","healthy","injury1","healthy","injury2", "injury1","healthy","injury2","healthy","injury2")) # 处理逻辑:按id分组,判断该组是否存在type包含"injury"的记录,生成injury_ind need <- have %>% group_by(id) %>% summarise(injury_ind = as.integer(any(grepl("injury", type)))) %>% ungroup() # 查看结果 print(need)
代码解释:
group_by(id):按id分组,确保每个id只处理一次any(grepl("injury", type)):检查当前id对应的所有type里,是否有任意一条包含"injury"字符串,返回TRUE/FALSEas.integer():把布尔值转换成0/1,符合你要的指示列格式
如果不想用dplyr,也可以用Base R实现:
# Base R方法 need_base <- aggregate(type ~ id, data = have, FUN = function(x) as.integer(any(grepl("injury", x)))) names(need_base)[2] <- "injury_ind" print(need_base)
SAS语言解决方案
SAS里可以用PROC SQL或者DATA步来实现,两种方法都给你:
方法1:PROC SQL(推荐,简洁高效)
/* 原始数据 */ data have; input id type $; datalines; 1 healthy 1 healthy 2 injury1 3 healthy 3 injury2 3 injury1 4 healthy 5 injury2 5 healthy 6 injury2 ; run; /* 生成目标数据 */ proc sql; create table need as select distinct id, case when exists(select 1 from have h2 where h2.id = h.id and h2.type contains 'injury') then 1 else 0 end as injury_ind from have h; quit; /* 查看结果 */ proc print data=need; run;
方法2:DATA步(适合习惯数据步操作的用户)
/* 先按id排序 */ proc sort data=have; by id; run; /* 数据步处理:保留每个id的第一条记录,同时标记是否有injury */ data need; set have; by id; retain has_injury 0; if first.id then has_injury = 0; if type contains 'injury' then has_injury = 1; if last.id then do; injury_ind = has_injury; output; end; keep id injury_ind; run;
SAS代码解释:
- PROC SQL里的
exists子查询:检查当前id是否存在任何包含"injury"的type,存在则返回1,否则0 - DATA步里用
retain保留变量值,first.id和last.id标记每个id组的首尾,最后输出每个id的最终指示值
这样处理后,就能得到你想要的去重id且带损伤指示列的目标数据啦!
内容的提问来源于stack exchange,提问作者the_data_guy
相关产品推荐
相关产品推荐

