如何编写可访问dplyr上下文数据的R自定义函数?
问题:在dplyr上下文实现自动获取数据的哑变量转因子函数
场景说明
现有如下数据框df:
# A tibble: 5 × 4 index a b c <int> <int> <dbl> <dbl> 1 1 0 0 1 2 2 1 0 0 3 3 0 1 0 4 4 0 1 0 5 5 1 0 0
最初参考eatATA::dummiesToFactor()实现了将哑变量合并为单个因子列的函数:
dum2fac <- function(data) { factor(names(data)[max.col(data)]) } # 调用方式 df %>% mutate(name = dum2fac(across(a:c)))
现在希望修改dum2fac(),使其支持更简洁的调用方式,无需手动传入across(),直接指定列范围即可,像这样:
df %>% mutate(name = dum2fac(a:c))
尝试了如下代码,但不知道如何替换???来获取dplyr上下文中的数据集:
dum2fac <- function(expr) { data <- select(???, {{expr}}) factor(names(data)[max.col(data)])}
核心需求是让函数像across()一样,自动访问dplyr上下文的数据集,无需显式传入。
解决方案
使用dplyr提供的cur_data()函数,它能在dplyr动词(如mutate)的上下文中直接获取当前处理的数据框,结合rlang的准引用{{}}捕获列选择表达式,即可实现需求:
library(dplyr) dum2fac <- function(expr) { # 获取dplyr上下文的当前数据,选择指定列 data_subset <- select(cur_data(), {{expr}}) # 按行找到最大值所在列,转为因子 factor(names(data_subset)[max.col(data_subset)]) }
测试验证
用以下测试数据验证:
set.seed(2023) df <- tibble(index = 1:5, a = sample(0:1, 5, TRUE), b = (1 - a) * sample(0:1, 5, TRUE), c = 1 - a - b) # 调用新函数 df %>% mutate(name = dum2fac(a:c))
运行后会得到包含新因子列name的数据框,每个值对应该行哑变量为1的列名。
补充说明
cur_data()是dplyr官方提供的函数,专门用于在dplyr操作的上下文中获取当前数据,比直接操作rlang的数据掩码更直观、易用。{{expr}}是rlang的准引用语法,用于捕获用户传入的列选择表达式(如a:c),并在函数内正确解析。
内容的提问来源于stack exchange,提问作者Ricardo Semião
相关产品推荐
相关产品推荐

