【问题标题】:R: Passing function argument to sqldfR:将函数参数传递给 sqldf
【发布时间】:2016-07-17 12:44:36
【问题描述】:

我看到了一个类似的问题hereexample 5 here,但我的示例无法正常工作。 我在 R 方面不是很有经验,所以也许这很愚蠢。 我只想有一个函数,参数是 sqldf 使用的列名

我的最佳猜测:

function1 <- function(x) {
    ranking_test <<- sqldf ('select $x from lat_lon_combo t1')
}

function1(t1.lat_lon)

结果

"mget 中的错误(words, envir, "any", NA, inherits = TRUE) : object 't1.lat_lon' 未找到”

虽然 t1.lat_lon 应该存在。 有什么想法吗?

【问题讨论】:

  • 如果abc 是不包含特殊字符的有效列名,则将sqldf 替换为fn$sqldf,然后function1("abc") 将起作用。请参见sqldf 主页上的示例5:@ 987654323@
  • 非常好!谢谢 t1.$x 在这种情况下完成了工作。感谢您的包裹,事实证明它对我非常有用。

标签: r sqldf


【解决方案1】:

常见错误。 列名t1.lat_lon 可能存在,但在您对function1 的调用中,您引用了一个名为t1.lat_lon变量,它不存在。

您有几个选项,为简单起见,我推荐第一个(字符串):

  1. 将其作为字符串传递,并使用pastesprintf 形成查询字符串。如:

    library(sqldf)
    func1 <- function(x) {
        sqldf(sprintf("select %s from mtcars where cyl > 7", x))
    }
    func1("disp")
    
  2. 如果你真的必须在没有引号的情况下引用它,你可以这样做,但在这种情况下它是不必要的复杂性(为了两个引号符号):

    func2 <- function(x) {
        sqldf(sprintf("select %s from mtcars where cyl > 7",
                      deparse(substitute(x))))
    }
    func2(disp)
    

    这种类型的取消引用在执行plot(disp ~ mpg, data = mtcars) 之类的操作时使用(并且很有用)(尽管使用公式的操作甚至略有不同)。在这些情况下,它以牺牲一些代码复杂性和间接性为代价来增加有用性。如果您不需要这个(并且根据您的示例,它看起来不像您这样做),那么为了简单起见,我会避免这种情况。

顺便说一句:在这两种情况下,我都会返回从 sqldf 返回的值,我选择(并且我强烈敦促)反对副作用,就像你在你的功能。 Side effects 可能是需要的,但如果可以避免,则可以提供更清晰和更可预测的功能。

【讨论】:

  • 非常感谢它运行良好!当然,这都是一大串!关于副作用,您是说使用函数写入“ranking_test”变量是不明智的吗?
  • 对于downvote,您能帮我了解可以改进的地方吗?当然,这有点骇人听闻,但评论将有助于改进我和将来参考的答案。
  • 通常使用fn$sqldf根据对问题的评论在SQL字符串中执行字符串插值。
  • 我明白了,当我回答时,评论不存在(或至少可见)。我对fn$ 方法不太熟悉,很有趣。感谢您的回复!