You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于R语言dplyr的filter_at处理缺失值的技术问询

解决dplyr筛选含缺失值列与另一列组合条件的问题

首先我先帮你复现测试用的数据框(注意R里的缺失值一般用NA,和NaN在筛选逻辑上处理逻辑一致):

df <- data.frame(
  ID = 1:3,
  bank = c("own", "own", NA),
  type = c("online", "offline", "total"),
  stringsAsFactors = FALSE
)

你的核心需求是筛选bank列为缺失值(NA/NaN)且type列为"total"的行,之前的filter_at写法问题出在逻辑方向和函数用法上:any_vars的作用是只要任意一个变量满足括号里的条件就保留行,但你需要的是两个条件同时成立,而且条件表达式也和需求不匹配。

最直观的正确写法

直接用filter函数把两个条件用&(逻辑与)连接,清晰易懂:

library(dplyr)
l1 <- df %>% filter(is.na(bank) & type == "total")
nrow(l1) # 输出1,完全符合你的预期

如果你想用dplyr推荐的across写法(替代旧的filter_at)

从dplyr 1.0.0版本开始,官方推荐用across替代filter_at这类scoped动词,如果你想尝试这种写法,可以这样写:

l1 <- df %>% 
  filter(
    across(bank, is.na),
    across(type, ~ .x == "total")
  )

本质和上面的写法逻辑一致,只是用across来指定列对应的判断规则。

为什么你的原命令不对?

拆解一下你的原代码逻辑:

vec <- c("total")
l1 <- df %>% filter_at(vars(type,bank), any_vars(!(. %in% vec) && (!is.na(.))))

这里的逻辑是:只要type或bank其中一个变量满足“不在vec里且不是缺失值”,就保留该行。

  • 对于type列:!(. %in% vec) 会筛选出"online"和"offline"(它们不在vec里),同时!is.na(.)都满足,所以前两行的type符合条件;
  • 对于bank列:!(. %in% vec) 会包含"own"和NA(NA不在vec里),但!is.na(.)只保留"own",所以前两行的bank符合条件;
    最终前两行都会被保留,nrow(l1)得到2,和你的预期不符。

内容的提问来源于stack exchange,提问作者Andi Maier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 10:27:40