2017-11-06 4 views
1

Ich benutze die sqldf Funktion, um wiederholt eine Teilmenge einer Tabelle gegen sich selbst zu verbinden. Der Wiederholungsprozess findet innerhalb einer for-Schleife statt. Ich habe gelesen, dass das Hinzufügen eines Index die Leistung dieser Joins here verbessern kann.R sqldf - Index innerhalb/außerhalb einer Schleife

Meine Frage ist - wenn ich das wiederholt in einer Schleife mache, bedeutet das, dass ich den Index jedes Mal neu erstellen muss, wenn die Schleife ausgeführt wird oder gibt es eine Möglichkeit, den Index außerhalb der Schleife "persistieren" zu lassen in der Schleife verwendet?

Mit anderen Worten, die ich nur diese Version gesehen habe:

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

Gibt es eine Möglichkeit, etwas zu tun wie folgt aus:

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') 
} 

EDIT:

> 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([email protected], statement) : 
    no such table: main.iris 
> sqldf("select count(*) from main.iris where Species <> 'virginica'") ## 
Error in rsqlite_send_query([email protected], statement) : 
    no such table: main.iris 
> 
> sqldf() 
<SQLiteConnection> 
    Path: :memory: 
    Extensions: TRUE 
> 

EDIT_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 

Antwort

2

Die no-Argument-Form sqldf kann zum Öffnen und Schließen einer Verbindung verwendet werden, so dass zwischen sqldf Anweisungen alle die gleiche Verbindung verwenden können.

Beachten Sie, dass wir uns auf die bereits hochgeladene Version der Tabelle beziehen können, indem wir uns auf Tabelle x als main.x beziehen; Andernfalls versucht jede sqldf, sie erneut hochzuladen. Sie könnten auch das Argument verbose = TRUE zu den mit ## markierten Anweisungen hinzufügen, um zu sehen, was passiert.

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() 

Es gibt einige Beispiele auf der sqldf github home page.

Eine andere Möglichkeit ist die direkte Verwendung von RSQLite.

Beachten Sie auch, dass Sie einen Vektor von SQL-Strings erzeugen könnte und den gesamten Vektor passieren sqldf: sqldf(v)

Noch eine weitere Möglichkeit rekursive SQLite Common Table Expressions zu verwenden ist. Google für weitere Informationen.

Beachten Sie, dass andere Anweisungen als select (wie create) zu einer Warnung unter RSQLite 2.0 führen, aber dennoch das richtige Ergebnis geben, also entweder die Warnung ignorieren oder eine frühere Version von RSQLite verwenden.

+0

Stimmt die obige Ausgabe überein? – screechOwl

+0

Ja, die Ausgabe in EDIT_2 der Frage sieht korrekt aus. –

Verwandte Themen