首页 > 解决方案 > R / nse / 变量到子函数的双重切换

问题描述

我有两个函数我想在一个包装函数中包装在一起以提高可用性。包装函数包括一个变量(数据框中的列名),该变量应从包装函数移交给子函数之一。

强烈简化示例:

子功能 1:创建数据

datafun <- function() {

    df_data <- data.frame(x = rep(1:20, 3), 
                          y = rnorm(60),
                          ga = sample(c("a", "b"), 30, replace = TRUE),
                          gb = sample(c("x", "y"), 20, replace = TRUE))

    df_data
}

子功能 2:绘图

plotfun <- function(df, gvar) {

    gvar_q = deparse(substitute(gvar))

    g <- ggplot2::ggplot(df, ggplot2::aes_string(x = "x", y = "y", color = gvar_q)) +
        ggplot2::geom_line() +
        directlabels::geom_dl(ggplot2::aes(label = {{gvar}}), method = list("last.points"))

    g
}

包装功能

wrapfun <- function(gvar) {

    dat <- datafun()
    plot <- plotfun(df = dat, gvar = {{gvar}})

    plot
}

测试

直接使用这两个子功能没有问题:

#works
d <- datafun()
plotfun(d, gvar = ga)

然而,使用包装功能会导致错误

# doesn't work
wrapfun(gvar = ga)
>Error in FUN(X[[i]], ...) : object 'ga' not found

请注意(据我所知),directlabels::geom_dl不接受aes_string作为解决方法。所以看来我不能gvar作为字符串移交给函数。

标签: rfunctionggplot2nsedirect-labels

解决方案


在最新版本的 中ggplot,您不使用deparse/substituteaes_string。您专门使用新的 quasinotation 语法。有了这个例子,你应该只做

plotfun <- function(df, gvar) {

   ggplot2::ggplot(df, ggplot2::aes(x = x, y = y, color = {{gvar}})) +
     ggplot2::geom_line() +
     directlabels::geom_dl(ggplot2::aes(label = {{gvar}}), method = list("last.points"))

}

然后您的功能将直接和内部工作wrapfun()


推荐阅读