data.table自定义函数如何同时支持传入数值与列名参数
data.table参数兼容数值/列名的最优实现
推荐优先使用判断逻辑更明确、无歧义的写法,仅在传入符合列名规则的字符串时读取列,其余场景直接使用传入值,代码如下:
library(data.table) df <- data.table(a = c(1:5), b = c(5:1), c = c(1, 3, 5, 3, 1)) myfunc <- function(val) { # 仅当输入为长度1的字符串且是当前数据集列名时,读取对应列 target <- if (is.character(val) && length(val) == 1 && val %in% names(df)) { df[[val]] } else { val } df[a >= target] }
两种调用方式均可正常返回预期结果:
# 传入固定数值,返回a列大于等于2的行 myfunc(2) # a b c #1: 2 4 3 #2: 3 3 5 #3: 4 2 3 #4: 5 1 1 # 传入列名字符串,返回a列大于等于c列对应值的行 myfunc("c") # a b c #1: 1 5 1 #2: 4 2 3 #3: 5 1 1
如果需要完全对标dplyr的{{效果,支持不带引号传入列名(比如直接调用myfunc(c)无需加引号),可以改用元编程适配写法,覆盖更多调用场景:
myfunc <- function(val) { val_expr <- substitute(val) # 处理字符串常量输入 if (is.character(val_expr) && length(val_expr) == 1 && val_expr %in% names(df)) { val_expr <- as.name(val_expr) } df[eval(substitute(a >= .v, list(.v = val_expr)))] } # 三种调用方式均正常运行 myfunc(2) myfunc("c") myfunc(c)
内容的提问来源于stack exchange,提问作者Jackdaw
相关产品推荐
相关产品推荐

