这是一个操纵语言而不是字符串的解决方案。您和其他人将来可能还会发现 op_literal() 很有用。
解决方案
助手:op_literal()
这个辅助函数 op_literal() 实际上操纵 R 语言本身在 许多 操作数中重复使用像 + 这样的二元运算符...即使二元运算符通常只接受 两个 操作数。调用op_literal(`+`, w, x, y, z) 实际上会在此处生成expression:w + x + y + z。
# Helper function to arbitrarily repeat a binary operation (like '+').
op_literal <- function(op, ...) {
# Capture the operator as a symbol.
op_sym <- rlang::ensym(op)
# Count the operands.
n_dots <- rlang::dots_n(...)
# Recursive case: a binary operator cannot handle this many arguments.
if(n_dots > 2) {
# Split off the final operand.
dots <- rlang::exprs(...)
dots_last <- dots[[n_dots]]
dots <- dots[-n_dots]
# Perform recursion for the remaining operands.
op_left <- rlang::inject(op_literal(
op = !!op_sym,
... = !!!dots
))
# Assemble recursive results into the full operation.
substitute(op(op_left, dots_last))
}
# Base case: the binary operator can handle 2(-) arguments.
else {
substitute(op(...))
}
}
注意
由于op_literal() 生成expression,如果您想要结果,您仍然需要evaluate:
op_exp <- op_literal(`+`, 1, 2, 3, 4)
op_exp
#> 1 + 2 + 3 + 4
eval(op_exp)
#> [1] 10
自定义函数:print.f()
接下来,这个自定义的print.f() 然后利用op_literal() 组装公式:
# Your custom 'print.f()' function.
print.f <- function(data, var1, ..., group) {
# Capture the core variables as symbols.
group_var <- rlang::ensym(group)
other_vars <- rlang::ensym(var1)
# Count the additional variables.
n_dots <- rlang::dots_n(...)
# Append those other variables if they exist.
if(n_dots > 0) {
other_vars <- rlang::inject(op_literal(op = `+`, !!other_vars, ...))
}
# Assemble the formula.
formula_exp <- rlang::inject(~ !!other_vars | !!group_var)
# Generate the table according to that formula.
table1::table1(
formula_exp,
data = data
)
}
结果
鉴于您的dataset 在此处转载
dataset <- data.frame(
ID = c(1, 1, 2, 2, 3, 3, 4, 4),
group = c("gp1", "gp2", "gp1", "gp2", "gp1", "gp2", "gp1", "gp2"),
col1 = c(0, 1, 1, 1, 0, 1, 1, 0),
col2 = c(0, 0, 1, 1, 1, 1, 0, 0),
col3 = c(1, 0, 1, 0, 1, 1, 1, 0)
)
您致电print.f()
print.f(dataset, col1, col2, col3, group = group)
应该产生以下可视化:
注意
就目前而言,您已经在函数头的end 处定义了group 参数。这意味着如果您尝试像这样调用print.f()
print.f(data = dataset, var = col1, col2, col3, group)
然后你会得到一个错误:如果没有group = 规范,最终变量会与col2 和col3 混为一谈,都在... 的保护伞下。这会产生一个错误的公式:
~ col1 + col2 + col3 + group |
为避免每次都必须输入group = 的痛苦,您可以简单地将其重新定位在... 之前,如下所示:
print.f <- function(data, group, var1, ...) {
# ^^^^^
完成此操作后,以下调用将按您的预期工作:
print.f(dataset, group, col1, col2, col3)