在 R 中,如何将参数作为字符串传递给像 plotXtabs2 这样的函数?

Posted

技术标签:

【中文标题】在 R 中,如何将参数作为字符串传递给像 plotXtabs2 这样的函数?【英文标题】:In R how to pass parameters to a functions like plotXtabs2 as strings? 【发布时间】:2020-05-08 19:52:58 【问题描述】:

PlotXTabs2 是一个函数,用于绘制类别变量之间的交叉表比例,其中有 3 个最小必需参数

PlotXTabs2( 数据, X, y)

作为数据框的数据,来自该数据框的 x 和 y 列名称。

我想在一个循环中调用它,其中列名 x、y 将是来自数据框 colnames() 的字符串,类似于 ....

varscat = colnames(df)

for(i in 1:(length(varscat)-1)) 

  for(j in (i+1):length(varscat))
  
     tmp <- df[,c(myvars[varscat[i]], myvars[varscat[j]])]

     # ...

     PlotXTabs2( df, x=myvars[varscat[i]], y=myvars[varscat[j]] ) 
 

我一直在尝试使用 eval、do.call 来跟踪示例,但没有成功,其中大多数都与预期用途是编写函数以接受参数作为字符串的情况有关。

我怎样才能达到这个结果?

【问题讨论】:

【参考方案1】:

您可以从rlang 使用!!

library(CGPfunctions)
#> Registered S3 methods overwritten by 'lme4':
#>   method                          from
#>   cooks.distance.influence.merMod car 
#>   influence.merMod                car 
#>   dfbeta.influence.merMod         car 
#>   dfbetas.influence.merMod        car
library(ggplot2)
out <- lapply(combn(colnames(mpg), 2, simplify = FALSE), 
       function(z) PlotXTabs2( mpg, !!z[1], !!z[2]) )
out[[3]] ## example plot from the list

由reprex package (v0.3.0) 于 2020 年 5 月 8 日创建

编辑:

变量对的顺序会影响绘图的生成方式。我们可以使用这样的函数专门选择对的第一个和第二个元素:

plotPairs <- function(xvals, yvals, data, ...)
    pairs <- as.list(data.frame(t(expand.grid(xvals, yvals))))
    lapply(pairs, function(z) PlotXTabs2( data, !!z[1], !!z[2], ...))


out <- plotPairs(
    xvals = c("vs", "cyl", "gear"),
    yvals = c("am", "carb"),
    data = mtcars, 
    ylab = NULL,
    perc.k = 1,
    palette = "Set2")

【讨论】:

好的,它可以工作,但是为什么当我尝试为 ggplot 应用相同的内容时它没有? >> vx = "mpg" vy = "disp" ggplot(mtcars, aes(x=!!vx, y= !!vy)) + geom_bar(stat="identity") ?`!!` 将为您提供如何传递的示例 - 是的,它有点复杂,但在这种情况下它是这样工作的:ggplot(mtcars, aes(x=!!sym(vx), y=!!sym(vy))) + geom_bar(stat="identity") 在我的回答中,用PlotXTabs2(mpg, !!sym(z[1]), !!sym(z[2])) 替换PlotXTabs2( mpg, !!z[1], !!z[2]) 也可以;作为概括,也许这样会更安全。 很高兴你发现这个包很有帮助@jcarlos。您可能还想查看关于使用pmap 交叉变量以及cross2_var_vectors 辅助函数ibecav.github.io/CGPfunctions/reference/cross2_var_vectors.html 的小插图的最后一部分【参考方案2】:

作为函数作者,我有义务展示我通常如何使用它,并避免引用问题。小插图和帮助文件显示了更复杂的示例,您可以在其中使用 pmap 构建标题等。

library(CGPfunctions)

# you can build by column number
# cross2_var_vectors(mtcars, 9, c(2, 10:11))
# or column name
# cross2_var_vectors(mtcars, "am", c("cyl", "gear", "carb"))
# build the vectors by hand
x2 <- c("am", "carb")
y2 <- c("vs", "cyl", "gear")
# cross2_var_vectors(mtcars, x2, y2, verbose = TRUE)

variables_list <- cross2_var_vectors(mtcars, x2, y2)

plotlist <- purrr::map2(
  .x = variables_list$lista
  .y = variables_list$listb,
  .f = CGPfunctions::PlotXTabs2,
  data = mtcars,
  ylab = NULL,
  perc.k = 1,
  palette = "Set2"
)

plotlist[[2]]

由reprex package (v0.3.0) 于 2020-05-11 创建

【讨论】:

我想知道您是否可以将更大的默认B 参数传递给sjstats::crosstable_statistics 使用的fisher.test,或者允许用户选择它 - 或者允许选择方法“phi " (chiq.test) 和 "auto",因为当 sjstats::crosstable_statistics 选择 "fisher" 时,B=2000 经常给出相当可变的 p 值。这将使结果更具可重复性。例如,在上面的示例图中,p 很容易在 0.005 和 0.015 之间变化。对于B = 1E6,它主要在 0.0090 和 0.0092 之间变化,因此仍然更接近 chisq 计算的 0.0091。 我去看看。你能帮我一个忙,把它放在这里,所以我不要忘记,我很少再关注 p 值了。

以上是关于在 R 中,如何将参数作为字符串传递给像 plotXtabs2 这样的函数?的主要内容,如果未能解决你的问题,请参考以下文章

R将分组列作为字符串传递给函数参数汇总。

将字符串传递给 R 函数参数,但稍后用作另一个函数的参数名称

如何在数学表达式中添加星号?

将 R 函数作为 Java 方法参数传递

将 JavaScript 函数作为参数传递

将 JavaScript 函数作为参数传递