tidyverse中filter筛选目标值不存在时如何返回完整tibble
筛选值不存在时返回原数据集的实现方案
问题场景
现有示例数据集:
tib <- tibble::tibble(col1 = c("a","a","b","b"))
直接执行dplyr::filter(tib, col1 == "c")会返回0行空结果,需要实现:若筛选的目标值不存在于目标列中,忽略过滤条件返回完整原数据集。
实现方法
方法1:单语句dplyr直接实现
不需要额外分支判断,直接在filter条件中增加存在性判断逻辑即可:
target_val <- "c" res <- dplyr::filter(tib, col1 == target_val | !target_val %in% col1)
逻辑说明:
- 若目标值
target_val存在于col1列中,!target_val %in% col1为FALSE,过滤条件等价于col1 == target_val,仅返回匹配行 - 若目标值不存在于
col1列中,!target_val %in% col1为TRUE,所有行都满足过滤条件,直接返回完整原数据集
方法2:分支判断写法(可读性更高)
如果需要更清晰的逻辑区分,可提前判断目标值是否存在,再执行对应操作:
target_val <- "c" if (target_val %in% tib$col1) { res <- dplyr::filter(tib, col1 == target_val) } else { res <- tib }
方法3:封装为自定义函数(可复用场景)
如果需要频繁调用该逻辑,可封装为通用函数:
filter_or_all <- function(data, filter_col, target_val) { col_vals <- dplyr::pull(data, {{ filter_col }}) if (target_val %in% col_vals) { dplyr::filter(data, {{ filter_col }} == target_val) } else { data } } # 调用示例 filter_or_all(tib, col1, "c") # 目标值不存在,返回全部数据 filter_or_all(tib, col1, "a") # 目标值存在,返回匹配行
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

