代码之家  ›  专栏  ›  技术社区  ›  screechOwl

R sqldf-循环内/外索引

  •  2
  • screechOwl  · 技术社区  · 7 年前

    我使用sqldf函数反复将表的子集与其自身连接。重复过程在for循环中发生。我已经读到,添加索引可以提高这些连接的性能 here .

    我的问题是——如果我在循环中重复这样做,这是否意味着每次循环执行时都必须重新创建索引,或者有没有办法让索引在循环外“持久化”,但在循环内使用?

    换句话说,我只看过这个版本:

    for(i in 1:10){
       df1 <- sqldf(c('create index...','select * from table1'))
    }
    

    有没有这样的方法:

    df1 <- sqldf('create index...') # create index outside of loop
    
    for(i in 1:10){
       df2 <- sqldf('select * from t1 left join t2 on t1.col1 = t2.col1')
    }
    

    编辑:

    > sqldf() 
    NULL
    > 
    > sqldf("create index idx on iris(Species)") ## 
    data frame with 0 columns and 0 rows
    > sqldf("select count(*) from main.iris where Species = 'virginica'") ##
    Error in rsqlite_send_query(conn@ptr, statement) : 
      no such table: main.iris
    > sqldf("select count(*) from main.iris where Species <> 'virginica'") ##
    Error in rsqlite_send_query(conn@ptr, statement) : 
      no such table: main.iris
    > 
    > sqldf()
    <SQLiteConnection>
      Path: :memory:
      Extensions: TRUE
    > 
    

    编辑2:

    > sqldf() 
    NULL
    > # close an old connection if it exists
    >    if (!is.null(getOption("sqldf.connection"))) sqldf()
    > sqldf() 
    <SQLiteConnection>
      Path: :memory:
      Extensions: TRUE
    > sqldf("create index idx on iris(Species)") ## 
    data frame with 0 columns and 0 rows
    > sqldf("select count(*) from main.iris where Species = 'virginica'") ##
      count(*)
    1       50
    > sqldf("select count(*) from main.iris where Species <> 'virginica'") ##
      count(*)
    1      100
    > sqldf() 
    NULL
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   G. Grothendieck    7 年前

    的无参数形式 sqldf 可用于打开和关闭连接,以便中间 语句都可以使用相同的连接。

    注意,我们可以通过参考表来参考已经上传的表的版本 x main.x ; 否则,每个 sqldf 将再次尝试上载。您也可以考虑添加 verbose = TRUE 标记为##的语句的参数,以查看发生了什么。

    library(sqldf)
    
    sqldf() 
    
    sqldf("create index idx on iris(Species)") ## 
    sqldf("select count(*) from main.iris where Species = 'virginica'") ##
    sqldf("select count(*) from main.iris where Species <> 'virginica'") ##
    
    sqldf()
    

    有一些例子 sqldf github home page .

    另一种可能是直接使用RSQLite。

    sqldf(v)

    还有一种可能性是使用SQLite递归公共表表达式。谷歌获取更多信息。

    注意,除 select (例如 create )在RSQLite 2.0下产生警告,但仍会给出正确的结果,因此请忽略该警告或使用RSQLite的早期版本。