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

如何用collapse/kit包替代R中dplyr的if_all和if_any函数

用collapse或kit包替代dplyr的if_all和if_any实现高效数据处理

在处理大型数据集时,dplyr的if_all和if_any可能存在性能瓶颈,使用collapse或kit包的对应函数可以获得更快的处理速度。以下是正确的实现方式,先分析原代码的问题:

原代码中使用fsum(fselect(., A2, A3) %in% c(1, 2))时,fsum默认按列求和,而非按行计算每行满足条件的元素数量,因此得到的结果不符合预期。


一、使用collapse包实现

collapse包提供了专门的行级逻辑判断函数,完美对应dplyr的两个函数:

  • frowall(x, cond):判断每行所有元素是否满足条件(等效if_all)
  • frowany(x, cond):判断每行任意元素是否满足条件(等效if_any)

正确代码

library(tidyverse)
library(collapse)

set.seed(12345)
df1 <- 
  data.frame(
    A1 = runif(n = 10, min = 1, max = 3) %>% round,
    A2 = runif(n = 10, min = 1, max = 4) %>% round,
    A3 = runif(n = 10, min = 1, max = 5) %>% round
  )

# 实现if_all和if_any的等效功能
df1 %>% 
  fmutate(
    A4 = frowall(fselect(., A2, A3), \(x) x %in% c(1, 2)),
    A5 = frowany(fselect(., A2, A3), \(x) x %in% c(1, 2))
  )

输出结果

A1 A2 A3    A4    A5
1   2  1  3 FALSE  TRUE
2   3  1  2  TRUE  TRUE
3   3  3  5 FALSE FALSE
4   3  1  4 FALSE  TRUE
5   2  2  4 FALSE  TRUE
6   1  2  3 FALSE  TRUE
7   2  2  4 FALSE  TRUE
8   2  2  3 FALSE  TRUE
9   2  2  2  TRUE  TRUE
10  3  4  3 FALSE FALSE

该结果与dplyr的if_all/if_any输出完全一致。

如果坚持使用fsum的方式,需指定按行求和(MARGIN=1),代码如下:

df1 %>% 
  fmutate(
    A4 = fsum(fselect(., A2, A3) %in% c(1, 2), MARGIN = 1) == 2,
    A5 = fsum(fselect(., A2, A3) %in% c(1, 2), MARGIN = 1) >= 1
  )

同样可以得到正确结果,但frowall/frowany更直观且性能更优。


二、使用kit包实现

kit包提供了row_all和row_any函数,直接实现行级的全满足/任意满足判断:

正确代码

library(tidyverse)
library(kit)

df1 %>% 
  mutate(
    A4 = row_all(fselect(., A2, A3) %in% c(1, 2)),
    A5 = row_any(fselect(., A2, A3) %in% c(1, 2))
  )

输出结果

与dplyr、collapse的结果完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:32:15