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

dplyr中pick()与c_across()在行缺失值统计中的差异及相关问题

dplyr中pick()与c_across()在行缺失值统计中的差异及相关问题

嘿,我来帮你逐个拆解这几个关于dplyr工具的问题,保证说得明明白白!

1. pick() 和 c_across() 到底有啥不一样?

简单来说,这俩函数在rowwise()环境下的返回类型完全不同:

  • pick() 返回的是迷你tibble(数据框):每行对应一个只包含当前行目标列的小数据框,完全保留原列的类型,哪怕各列类型不一样也能正常处理。
  • c_across() 返回的是原子向量:它会把当前行目标列的值合并成一个单一向量,这就要求这些列的类型能被兼容转换(比如数值和字符会被统一转成字符型),如果类型差异太大,很容易触发意外行为。

2. 怎么让第二个代码块正常工作?

你的第二个代码块出问题的核心原因是:c_across() 试图把字符型的a_letter和数值型的a_number合并成一个向量,虽然类型转换能完成,但有时候会因为类型兼容问题导致sum(is.na(...))无法正确计算(比如旧版dplyr里可能返回列表而非向量)。

给你两个实用的修复方案:

方案一:手动遍历判断缺失值

不管列类型如何,都能准确统计缺失值:

tibble(
  a_letter=sample(c(NA,"a","b"),size = 10,replace = T),
  a_number=sample(c(NA,1,2),size = 10,replace = T),
  hi="world"
) |> 
  rowwise() |> 
  mutate(empty_measurements = c_across(matches("a_")) %>% lapply(is.na) %>% unlist() %>% sum())

方案二:跳出rowwise,用更高效的写法

其实统计每行缺失值根本不需要rowwise(),直接用rowSums结合select更简洁高效:

tibble(
  a_letter=sample(c(NA,"a","b"),size = 10,replace = T),
  a_number=sample(c(NA,1,2),size = 10,replace = T),
  hi="world"
) |> 
  mutate(empty_measurements = rowSums(is.na(select(matches("a_")))))

3. 为啥有人会觉得pick()是个坏选择?其实它在这里反而更靠谱!

你说反啦!在这个统计跨列缺失值的场景里,pick()才是更安全的选择,根本不是坏选择:

  • 它保留了原数据的列结构,不需要做任何类型转换,is.na(pick(...))会逐个判断每个列的缺失值,sum()在rowwise()环境下会自动把当前行的所有布尔值加总,完美统计缺失数量。
  • 而c_across()反而受限于向量的类型统一性,当列类型多样时,要么被迫做类型转换(可能隐藏风险),要么在旧版本里直接报错。

所以你的直觉其实没问题,但这里pick()的表现比c_across()更适配这个需求哦!

备注:内容来源于stack exchange,提问作者Aegis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 08:55:34