我有兩個大數據框,我想用外部連接merge()
,但連接的表對RAM太大。我的解決方法是使用RSQLite
包到外部聯接並將聯接的表存回數據庫。使用RSQLite將列追加到R中的SQLite表
我想在這個連接表中的列上使用R函數,但我無法弄清楚如何在連接表中追加一列。我知道如何處理dbWriteTable()
(如下所示),但這不是一個選項,因爲連接表比RAM大。
library(RSQLite)
left <- data.frame(let = letters[rep(1:4, each = 5)], num = 1:20)
right <- data.frame(let = letters[rep(1:4, each = 5)], num = 21:40)
con <- dbConnect(dbDriver("SQLite"), dbname = tempfile())
dbWriteTable(con, "left_table", left, row.names = F)
dbWriteTable(con, "right_table", right, row.names = F)
dbGetQuery(con, "CREATE TABLE merged_table (letters TEXT, left_num INTEGER, right_num INTEGER)")
dbGetQuery(con, "INSERT INTO merged_table SELECT * FROM left_table LEFT OUTER JOIN right_table USING (let)")
fun <- function(x) rowSums(x)
temp <- dbReadTable(con, "merged_table")
dbWriteTable(con, "merged_table_new", cbind(temp, fun(temp[, 2:3])))
dbDisconnect(con)
我聽說數據庫上的行工作,所以我懷疑是正確的解決方案可能只是通過行週期,附加到每一行的條目,但我不知道如何實現。謝謝!
(還有什麼神聖約的SQLite這裏,我只是認爲這將是這個特設分析更好。)
編輯:我在dbGetPreparedQuery()
瞭解了bind.data
選項,並意識到我需要一個讀取和寫入連接到數據庫,但我仍然有一些問題(即數據庫沒有INSERT
)。該腳本運行沒有錯誤,但也沒有所需的結果。
library(RSQLite)
left <- data.frame(let = letters[rep(1:4, each = 5)], num = 1:20)
right <- data.frame(let = letters[rep(1:4, each = 5)], num = 21:40)
my.tempfile <- tempfile()
con.write <- dbConnect(dbDriver("SQLite"), dbname = my.tempfile)
con.read <- dbConnect(dbDriver("SQLite"), dbname = my.tempfile)
dbWriteTable(con.write, "left_table", left, row.names = F)
dbWriteTable(con.write, "right_table", right, row.names = F)
dbGetQuery(con.write, "CREATE TABLE merged_table (letters TEXT, left_num INTEGER, right_num INTEGER)")
dbGetQuery(con.write, "INSERT INTO merged_table SELECT * FROM left_table LEFT OUTER JOIN right_table USING (let)")
dbGetQuery(con.write, "ALTER TABLE merged_table ADD COLUMN sum INTEGER")
dbGetQuery(con.write, "ALTER TABLE merged_table ADD COLUMN mean INTEGER")
res <- dbSendQuery(con.read, "SELECT left_num, right_num FROM merged_table")
while (!dbHasCompleted(res)) {
data.1 <- fetch(res)
data.2 <- data.frame(rowSums(data.1), rowMeans(data.1))
dbGetPreparedQuery(con.write, "INSERT INTO merged_table (sum, mean) VALUES (?, ?)", bind.data = data.2)
}
dbClearResult(res)
dbGetQuery(con.read, "SELECT * FROM merged_table LIMIT 5")
給
letters left_num right_num sum mean
1 a 1 21 NA NA
2 a 1 22 NA NA
3 a 1 23 NA NA
4 a 1 24 NA NA
5 a 1 25 NA NA
,但我預計
left_num right_num sum mean
1 1 21 22 11.0
2 1 22 23 11.5
3 1 23 24 12.0
4 1 24 25 12.5
5 1 25 26 13.0
感謝您的一些額外的部分!我想我更接近一點,我更新了我的問題。 –
謝謝!我同時想到了這一點。我花了一段時間才意識到,即使我使用INSERT指定了列,但它仍在追加,而且我需要第二個數據庫,因爲SQLite會鎖定數據庫。謝謝您的幫助! –