2017-10-12 2 views
0

Ich habe eine Liste von Datenrahmen, die ich eine Zusammenführung durchführen möchte. Wie kann ich jedes Element der Liste an die jeweilige sqldf-Anweisung übergeben? Mein Code ist wie folgt:Übergeben von Listen an sqldf

require(sqldf) 
a <- data.frame(ID=c("a","b","c","d","a","a"),num=1:6,num2=2:7) 
b <- data.frame(ID=c("d","a","a","a","b","c"),num=6:1,num2=7:2) 
Datalist <- list(a,b) 
mergeto <- data.frame(ID=c("a","a","a","b","c","d"),name=rep("A",6),name2=rep("B"),6) 
test <- sqldf(" 
select * 
from Datalist[[1]] as a left outer join mergeto as b 
where a.ID = b.ID and 
") 

ich den Fehler:

Fehler in rsqlite_send_query (conn @ ptr, Statement): unerkannt Token: "]"

Gibt es eine Möglichkeit zu Verwenden Sie die Listenvariablen direkt von R? Ich meine, ich weiß, ich könnte a <- Datalist[[1]] verwenden und dann a in der sqldf-Anweisung verwenden, aber auf diese Weise erstellen Sie eine Kopie von Datalist-Elemente jedes Mal und Datalist ist bereits sehr groß..ich bin sicher, dass es einen Weg geben muss. Um auch direkt auf Variablen zugreifen zu können, die Strings enthalten, muss es einen Weg geben? Also, was ich am Ende tun möchte, ist SQL-Anweisungen in einer Schleife durchzuführen, also muss ich auch in der Lage sein, den Index innerhalb der Anweisung zu ändern. Aber weil es eine Saite ist, scheint es nicht mehr so ​​einfach zu sein.

+0

Sie wirklich tun Brauchen Sie 'sqldf'? Das Zusammenführen einer Liste von Datenrahmen ist ziemlich gut abgedeckt [in dieser R-FAQ] (https://stackoverflow.com/q/8091303/903061). 'base :: merge',' data.table :: merge' und 'dplyr :: left_join' sind alle in der Lage, einen Linksbündig zu machen. – Gregor

+0

ja ich brauche, weil ich einige komplizierte merge Bedingungen habe. Ich glaube nicht, dass ich Basis-Merge dafür verwenden kann, zumindest war es nicht möglich, als ich vor ungefähr einem Jahr nachgesehen habe. Wenn Base Merge alles SQL machen kann, dann würde ich ja sofort wechseln. – EDC

+0

'data.table' kann nicht-equi-Joins ausführen, obwohl es nicht die' merge'-Funktionalität (AFAIK) verwendet. Ich denke, Ihre beste Wette mit SQL df ist, (1) Ihre Liste zu benennen, (2) 'list2env' zu verwenden, um Ihre Daten in eine Umgebung zu bringen, (3) diese Umgebung mit dem' envir' Argument von SQL df anzugeben, und (4) "fügen" Sie die SQL-Anweisungen mit den Namen Ihrer Listen zusammen. Vielleicht möchten Sie eine andere Frage mit einem Beispiel Ihrer komplizierten Bedingungen stellen, um zu sehen, ob es mit einer Liste von 'data.tables' und ihren erweiterten Funktionen möglich ist. – Gregor

Antwort

2

Versuchen Sie Folgendes, was bereits von @Gregor in einem Kommentar beschrieben wurde, aber hier machen wir es explizit. Wir verwenden eine namens Liste L bestehend aus drei Datenrahmen, von denen jeder dem eingebauten BOD Datenrahmen entspricht und den zweiten und folgenden Datenrahmen an den ersten an Time anschließt, der den Text der SQL-Anweisung sql aus seinen zwei Teilen konstruiert: sel_from (eine Zeichenfolge, die die Auswahl und von enthält) und joins (ein Zeichenvektor von Join-Definitionen).

library(sqldf) 

L <- list(BOD1 = BOD, BOD2 = BOD, BOD3 = BOD) # named list as input 
nms <- names(L) 
sel_from <- sprintf("select * from %s", nms[1]) 
joins <- sprintf("join %s on %s.Time = %s.Time", nms[-1], nms[-1], nms[1]) 
sql <- paste(c(sel_from, joins), collapse = "\n") 
sqldf(sql, envir = list2env(L)) 

Dies ergibt die folgende Ausgabe:

Time demand Time demand Time demand 
1 1 8.3 1 8.3 1 8.3 
2 2 10.3 2 10.3 2 10.3 
3 3 19.0 3 19.0 3 19.0 
4 4 16.0 4 16.0 4 16.0 
5 5 15.6 5 15.6 5 15.6 
6 7 19.8 7 19.8 7 19.8 

Auch können wir auf den Inhalt von sql wie folgt aussehen:

cat(sql, "\n") 

geben:

select * from BOD1 
join BOD2 on BOD2.Time = BOD1.Time 
join BOD3 on BOD3.Time = BOD1.Time