【问题标题】:Using sqldf with r variable containing underscore in its name将 sqldf 与名称中包含下划线的 r 变量一起使用
【发布时间】:2018-11-06 14:01:33
【问题描述】:

这段代码

> A <- data.frame(col1 = c(1,2,3),col2 = c("red","blue","green"))
> color_num <- 2
> fn$sqldf("select * from A where col1 >= '$color_num'")

产生错误

eval(parse(text = paste(..., sep = "")), env) 中的错误:对象 找不到“颜色”

但是,如果变量color_num 被赋予一个不带下划线的名称(例如colornum),那么执行fn$sqldf("select * from A where col1 &gt;= '$colornum'") 会产生预期的结果而不会出现错误。

我相信sqldf 在幕后将下划线替换为句点,导致它将下划线前面的组件视为表格,将下划线后面的部分视为列名。 This answer(和 cmets)对sqldf 中关于列名的问题表示该库曾经用下划线替换了点,但现在不再这样做,但我找不到任何关于用点替换下划线的信息。

这是一个问题,因为我使用的命名约定大量使用下划线作为变量名。

有什么方法可以在 sqldf 查询中获取带有下划线的变量名?

【问题讨论】:

    标签: r naming-conventions sqldf


    【解决方案1】:

    你可以使用反引号:

    fn$sqldf("select * from A where col1 >= `color_num`")
    ##   col1  col2
    ## 1    2  blue
    ## 2    3 green
    

    【讨论】:

      【解决方案2】:

      您可以在sql 代码周围使用paste0,以便r 将color_num 评估为2,然后将其粘贴到一个sql 语句中。

      library(sqldf)
          A <- data.frame(col1 = c(1,2,3),col2 = c("red","blue","green"))
          color_num <- 2
      
          fn$sqldf(paste0("select * from A where col1 >=",color_num))
      

      如果你想使用$var 方法并且遇到_ 的问题,这里有一个解决方法来让所有变量都有。而不是 _ ,这可能效率低下但有效。

      color_col <- "blue"
      #get list of values with underscores and not your df
      nms <- setdiff(ls(),c("A"))
      #change name of list to have '.' instead of '_'
      setNames(nms,gsub("_",".",nms))
      #Assign values to names with '.'s
      myvars <- lapply(setNames(nms,gsub("_",".",nms)), function(x){
        assign(gsub("_",".",x) , get(x))})
      #bring them to global env
      list2env(myvars,.GlobalEnv)
      
      #run example query
      fn$sqldf("select * from A where col1 >= '$color.num' and col2 = '$color.col' ")
      

      【讨论】:

      • 谢谢@Mike。我尝试将 [ ] 包裹在变量名周围,但无济于事。关于用paste0 构造字符串,这并不理想,因为变量名可以出现在复杂的sql 字符串中的许多地方,所以我必须paste0 将许多不同的子字符串放在一起。理想的解决方案是允许在sqldf 中使用标准变量名来适应变量名中常见的下划线。有没有办法做到这一点?
      • 我看到了问题。这可能是sql 包中的一个错误,这是一个解决方案,您可以将_ 更改为.,以便您的代码可以正常工作。如果你喜欢这个,我将使用lapply 扩展它以更改所有变量。 -assign(gsub("_",".",setdiff(ls(),c("A") )) ,get(setdiff(ls(),c("A") )))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 1970-01-01
      • 2014-04-19
      相关资源
      最近更新 更多