基于条件提取列名至新变量并聚合统计的R语言实现求助
R语言数据处理实现方案
先拿个示例数据框来演示,假设你的数据长这样:
library(tidyverse) # 构造示例数据 df <- tibble( SUBID = c("01001", "01002", "02001", "02002", "03001"), ABC = c(1, -2, 3, -4, 5), BCD = c(-1, 2, -3, 4, -5), DEF = c(1, -2, -3, 4, 5) )
第一步:为每个SUBID生成负数列名变量
用rowwise()结合c_across()逐行处理,筛选出数值为负的列名,再用str_c()合并成字符串:
df_step1 <- df %>% rowwise() %>% mutate(neg_cols = str_c(names(.)[c_across(ABC:DEF) < 0], collapse = ", ")) %>% ungroup() # 输出结果 df_step1
得到的neg_cols列就是每行里值为负的列名,比如第一行是"BCD",第二行是"ABC, DEF"。
第二步:按通用ID聚合统计唯一列名数量
先把SUBID截取前两位作为通用ID,再把neg_cols拆分成单独的列名行,最后分组统计每个通用ID对应的唯一列名数:
df_step2 <- df_step1 %>% mutate(general_id = str_sub(SUBID, 1, 2)) %>% separate_rows(neg_cols, sep = ", ") %>% group_by(general_id) %>% summarise(unique_neg_col_count = n_distinct(neg_cols)) %>% ungroup() # 输出结果 df_step2
跳过第一步直接完成第二步的方法
完全可以不用生成中间的neg_cols列,直接把数据转成长格式处理,效率更高:
df_direct_step2 <- df %>% pivot_longer(cols = ABC:DEF, names_to = "col_name", values_to = "value") %>% filter(value < 0) %>% mutate(general_id = str_sub(SUBID, 1, 2)) %>% group_by(general_id) %>% summarise(unique_neg_col_count = n_distinct(col_name)) %>% ungroup() # 输出结果和第二步完全一致 df_direct_step2
这个方法直接跳过了逐行生成合并列名的步骤,通过宽转长筛选负数行,再直接分组统计,代码更简洁,处理大数据时效率也更高。
内容的提问来源于stack exchange,提问作者sucksatmath
相关产品推荐
相关产品推荐

