在R语言成对DataFrame中通过列匹配条件创建新列并汇总数据
问题分析与代码修正
需求说明
需要基于数据框中第4列和第6列的条件匹配创建新列(第9列),规则如下:
- 若第4列为NA,新列取第6列的值
- 若第6列为NA,新列取第4列的值
- 若两列值相同,新列取该值
- 若两列值不同,复制该行并分别将新列设为第4列和第6列的值
最终按Method和Cluster分组,汇总relation的均值以及GenA的唯一值数量。
原代码存在的问题
- 循环索引错误:
length(probe)返回数据框的列数,遍历行应该用nrow(probe) - 条件判断无互斥:多个独立
if会依次执行,可能覆盖之前的赋值结果 - 语法与逻辑错误:最后一个
if位于循环外部,i的取值不符合预期;复制行的代码rep(probe[i,1:9]%>%probe[i,9]<-probe[i,6}完全不符合R语法 - 汇总代码不规范:
summarise中的均值未命名,后续使用不便;length(unique(GenA))可替换为更高效的n_distinct()
修正后的代码
# 加载dplyr包(如果未安装先执行 install.packages("dplyr")) library(dplyr) # 初始化Cluster列 probe$Cluster <- "cluster" # 第一步:处理NA和两列值相同的情况,标记需要拆分的行 probe <- probe %>% mutate(temp_col = case_when( is.na(.[[4]]) ~ .[[6]], is.na(.[[6]]) ~ .[[4]], .[[4]] == .[[6]] ~ .[[4]], TRUE ~ NA_character_ # 两列值不同时标记为NA,后续拆分 )) # 第二步:拆分两列值不同的行 split_rows <- probe %>% filter(is.na(temp_col)) split_rows1 <- split_rows %>% mutate(temp_col = .[[4]]) split_rows2 <- split_rows %>% mutate(temp_col = .[[6]]) # 合并处理后的数据 probe_processed <- probe %>% filter(!is.na(temp_col)) %>% bind_rows(split_rows1, split_rows2) # 将临时列赋值到第9列 probe_processed[[9]] <- probe_processed$temp_col # 第三步:按要求汇总数据 Sum <- probe_processed %>% group_by(Method, Cluster) %>% summarise( mean_relation = mean(relation, na.rm = FALSE), # 保留NA,若需忽略NA可改为TRUE number_observations = n_distinct(GenA) ) %>% data.frame()
说明
- 用
case_when()替代循环,更符合R的向量化操作逻辑,效率更高 - 拆分不同值的行时,通过提取、复制、合并的方式实现,避免循环出错
n_distinct()是dplyr中专门用于计算唯一值数量的函数,比length(unique())更高效
内容的提问来源于stack exchange,提问作者portillanath
相关产品推荐
相关产品推荐

