2017-10-12 80 views
0

我有一個數據框的列表,我想執行一個合併。我如何將列表中的每個元素傳遞給相應的sqldf語句? 我的代碼如下:傳遞列表到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 
") 

我得到的錯誤:

錯誤rsqlite_send_query(康涅狄格州@ PTR,語句): 無法識別的記號 「]」

有什麼辦法直接從R使用列表變量?我的意思是我知道我可以使用a <- Datalist[[1]],然後在sqldf語句中使用a,但這種方式每次都會創建一個Datalist元素的副本,並且Datalist已經非常大。我確信必須有一種方法。還要直接訪問包含字符串的變量,必須有辦法嗎? 所以我最終想做的是在循環中執行SQL語句,所以我還必須能夠更改語句中的索引。但是因爲它是一個字符串,它似乎不再可能了。

+0

你真的需要使用'sqldf'?合併數據幀列表已經很好地涵蓋了[在這個R-FAQ中](https://stackoverflow.com/q/8091303/903061)。 'base :: merge','data.table :: merge'和'dplyr :: left_join'完全可以做左連接。 – Gregor

+0

是的,我需要,因爲我有一些複雜的合併條件。我不認爲我可以使用base merge,至少在1年前檢查時是不可能的。如果基本合併可以完成SQL的所有功能,那麼是的,我會立即切換。 – EDC

+0

'data.table'可以執行非平等連接,但不使用它的「合併」功能(AFAIK)。我認爲使用SQL df最好的選擇是(1)爲列表命名,(2)使用'list2env'將數據放入環境中,(3)使用SQL df的'envir'參數指定該環境,以及4)將sql語句與列表名稱粘貼在一起。你可能想用一個複雜條件的例子來問另一個問題,看看是否有可能使用'data.table'及其高級特性列表。 – Gregor

回答

2

請嘗試下面的內容,@Gregor已經在評論中列出了這些內容,但在這裏我們將其明確指出。我們使用名爲的名稱爲的列表L由三個數據幀組成,每個數據幀均等於內置的BOD數據幀,並將第二個和隨後的數據幀連接到第一個Time,從其兩部分構建SQL語句sql的文本: sel_from(包含select和from的字符串)和joins(連接定義的字符向量)。

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

這給出了以下的輸出:

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 

此外,我們可以看看sql的內容是這樣的:

cat(sql, "\n") 

,並提供:

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