将多个变量输入到 R 函数中
Posted
技术标签:
【中文标题】将多个变量输入到 R 函数中【英文标题】:Enter multiple variables into an R function 【发布时间】:2022-01-12 18:25:50 【问题描述】:我想,并且我想将它们全部输入 table1()
函数 ==> 类似于这一行 tab<-table1(~ var1+var2+ var3+...+varN|group, data=data)
library(table1)
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 <- function(data,var1,...,group)
tab<-table1(~ var1+...|group, data=data)
tab
print.f(data,var1,var2,var3,group=group)
print.f(dataset,col1,col2,col3)
例如,如果我有一个包含 3 列以上的数据集,并且我想查看它们的输出,我该如何输入所有这些列?
【问题讨论】:
好的,那么当你尝试的时候发生了什么?有什么问题? @camile,我如何在 table1() 中输入我想要的变量数?我对帖子进行了编辑以使我的问题更清楚 adv-r.hadley.nz/functions.html#fun-dot-dot-dot 【参考方案1】:将公式创建为字符向量,转换为公式类并运行 table1。在示例中,我们展示了几种使用 print.f 或直接使用 table1 创建相同输出的方法。
print.f <- function(data, ..., group)
v <- paste(c(...), collapse = "+")
if (!missing(group)) v <- paste(v, "|", group)
fo <- as.formula(paste("~", v))
table1(fo, data = data)
library(table1)
print.f(dataset, "col1", "col2", "col3", group = "group")
print.f(dataset, c("col1", "col2", "col3"), group = "group")
print.f(dataset, grep("col", names(dataset), value = TRUE), group = "group")
print.f(dataset, names(dataset)[2:4], group = "group")
print.f(dataset[-1], ".", group = "group")
print.f(dataset, ". - ID", group = "group")
table1(~ . | group, dataset[-1])
table1(~ . - ID | group, dataset)
【讨论】:
非常漂亮!就我而言,我对一种面向语言的方法(而不是带有paste
d 字符串的方法)很感兴趣,在此过程中,我想出了op_literal()
函数,如above 所示。你知道是否已经存在类似的功能吗?我无法找到任何东西,所以我必须自己制作。
@Greg, reformulate(c("a", "b", "c"))[[2]]
提供与 op_literal(`+`, a, b, c)
相同的输出
太棒了!对于任意大的操作数集,是否有一个函数可以扩展到任何二元运算符?还是只有+
用于公式?
我不这么认为。重新制定旨在与回归公式一起使用。
很高兴知道!如果我可以让op_literal()
与像dplyr::`%>%`
这样的打包操作数很好地配合,这些操作数是完全合格的,但不能强制转换为symbol
,那么我实际上可能有一些东西!【参考方案2】:
这是一个操纵语言而不是字符串的解决方案。您和其他人将来可能还会发现 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
,如果您想要结果,您仍然需要eval
uate:
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)
【讨论】:
以上是关于将多个变量输入到 R 函数中的主要内容,如果未能解决你的问题,请参考以下文章