R语言中标记大数据框中与小数据框不同的行
问题:标记大DataFrame中不在小DataFrame里的行并高亮
我有两个DataFrame,希望将较大的ex1_df中不存在于较小ex_df的行高亮(标记为浅红色)。示例数据的R代码如下:
response <- c("Best overall", "Best overall", "Diease control", "Diease control", "Observed response", "Observed respone") value <- c("pd", "sd", "yes", "no", "yes", "no") drug <- c(10, 2, 0, 12, 0, 12) ex_df <- data.frame(response, value) ex_df <- data.frame(ex_df, drug) response1 <- c("Best overall", "Best overall", "Best overall", "Best overall", "Best overall", "Best overall", "Diease control", "Diease control", "Observed response", "Observed respone") value1 <- c("cr", "pr", "sd", "pd", "NE", "NA", "yes", "no", "yes", "no") drug1 <- c(0, 0, 2, 10, 0, 0, 0, 12, 2, 10) ex1_df <- data.frame(response1, value1) ex1_df <- data.frame(ex1_df, drug1)
需要标记ex1_df中的第1、2、5、6行。实际数据列名一致,可调整示例列名。我尝试了以下代码但得到空DataFrame,寻求解决方案:
deltas <- diffdf(base=ex1_df, compare=ex_df) var_list <- colnames(ex1_df) delta_list <- list() for(i in var_list) { dat <- data.frame(eval(parse(text = paste0("deltas$VarDiff_", i)))) %>% janitor::clean_names() delta_list[[i]] <- dat } delta_data <- do.call(rbind, delta_list)
解决方案
核心问题分析
你之前的代码得到空结果,本质原因是两个DataFrame的列名不匹配:ex1_df的列名是response1/value1/drug1,而ex_df是response/value/drug,导致diffdf无法正确识别行的匹配关系,自然找不到差异。
步骤1:统一列名
先将ex1_df的列名调整为和ex_df一致,这是行匹配的前提:
colnames(ex1_df) <- colnames(ex_df)
步骤2:定位差异行
用dplyr的anti_join可以直接获取ex1_df中不存在于ex_df的行,再提取这些行的索引:
library(dplyr) # 获取差异行内容 diff_rows <- anti_join(ex1_df, ex_df, by = colnames(ex_df)) # 获取差异行在ex1_df中的位置索引 diff_indices <- which(!apply(ex1_df, 1, function(row) any(apply(ex_df, 1, function(ref_row) all(row == ref_row)))))
步骤3:高亮差异行
这里提供两种常用的高亮方式:
方式1:用formattable快速实现
library(formattable) formattable(ex1_df, list( # 给差异行设置浅红色背景 area(row = diff_indices) = formatter("span", style = ~ style("background-color", "#ffebee")) ))
方式2:用gt实现更灵活的格式化
library(gt) ex1_df %>% gt() %>% tab_style( style = cell_fill(color = "#ffebee"), locations = cells_body(rows = diff_indices) )
修复你原有的diffdf代码
统一列名后,原代码可以正常获取差异:
library(diffdf) library(janitor) deltas <- diffdf(base = ex1_df, compare = ex_df) var_list <- colnames(ex1_df) delta_list <- list() for(i in var_list) { dat <- data.frame(eval(parse(text = paste0("deltas$VarDiff_", i)))) %>% clean_names() delta_list[[i]] <- dat } delta_data <- do.call(rbind, delta_list)
此时delta_data会包含正确的列差异信息,而deltas$RowDiff可以直接查看差异行的索引。
内容的提问来源于stack exchange,提问作者samthecodegod
相关产品推荐
相关产品推荐

