2015-11-27 2 views
2

Я пытаюсь объединить или переписать 12 лет данных опроса, каждый из которых содержит несколько миллионов наблюдений и сотни переменных, чтобы анализировать годовые тенденции при учете обзора состав. Недавняя версия MonetDBLite для R представляет собой отличную возможность реализовать основанные на столбцах СУБД для этого большого набора данных. Я, однако, испытываю трудности с объединением наборов данных.Невозможно объединить большие данные съемки в R с использованием MonetDB и MonetDBLite

Вкратце, используя plyr :: r.bind.fill для DBI: dbWriteTable возвращает усеченную таблицу. r.bind.fill является идеальным, потому что наборы данных отличаются друг от друга из года в год. Использование dplyr :: rbind_all вообще не работает. Менее полезный подход (но все же приемлемый) включает в себя удаление столбцов, чтобы сделать таблицы одинаковыми и использовать прямолинейную операцию UNION ALL SQL. Но это возвращает синтаксические ошибки.

Я очень новичок в dplyr и MonetDB, поэтому это, безусловно, связано с моим собственным невежеством, но я потратил пару дней на чистку сети без везения, поэтому любая помощь будет принята с благодарностью.

Ниже приведен воспроизводимый пример.

Приветствия

Чарльз

# install.packages("MonetDB.R", repos="http://dev.monetdb.org/Assets/R/") 
# install.packages("MonetDBLite", repos="http://dev.monetdb.org/Assets/R/") 
library(MonetDBLite) 
library(MonetDB.R) 
library(dplyr) 
library(plyr) 
library(zoo) 


mtcars1<-mtcars[,-11] # create 2 slightly different versions of mtcars 
mtcars2<-mtcars[,-10] 

mtcars1<-coredata(mtcars1)[rep(seq(nrow(mtcars1)),200000),] # create large versions of those dataframes 
mtcars2<-coredata(mtcars2)[rep(seq(nrow(mtcars2)),200000),] 

dbdir <- tempdir() # create a temporary directory 
con <- dbConnect(MonetDB.R(), embedded=dbdir) # use DBI to connect to MonetDB 

dbWriteTable(con, "mtcars1", mtcars1) # write the dataframes to column-based MonetDB tables 
dbWriteTable(con, "mtcars2", mtcars2) 
dbListTables(con) 

ms <- src_monetdb(embedded=dbdir) # create a dplyr::tbl version tables 
mt1 <- tbl(ms, "mtcars1") 
mt2<-tbl(ms, "mtcars2") 

# try plyr::rbind.fill to concatenate tables 
dbWriteTable(con, "mt_1_2", rbind.fill(as.data.frame(mt1, mt2))) 

# Warning message: 
# Only first 6,400,000 results retrieved. Use n = -1 to retrieve all. 

dbGetQuery(con, "SELECT COUNT(*) FROM mt_1_2 ") 
#  L1 
# 1 1e+05 

dbRemoveTable(con, "mt_1_2") # remove table to re-try 

# try dbFetch(res, n=-1) to retrieve all results 
dbFetch(dbWriteTable(con, "mt_1_2", rbind.fill(as.data.frame(mt1, mt2))), n=-1) 

# Error in (function (classes, fdef, mtable) : 
# unable to find an inherited method for function ‘dbFetch’ for signature ‘"logical", "numeric"’ 
# In addition: Warning message: 
# Only first 6,400,000 results retrieved. Use n = -1 to retrieve all. 

dbRemoveTable(con, "mt_1_2") # remove table to re-try 

dbListFields(con, "mtcars1") # remove fields to make table columns identical 
dbListFields(con, "mtcars2") 

dbGetQuery(con, " 
ALTER TABLE mtcars1 
DROP COLUMN gear 
") 

dbGetQuery(con, " 
ALTER TABLE mtcars2 
DROP COLUMN carb 
") 

dbGetQuery(con, 
    "CREATE TABLE mt_1_2 WITH 
    Select * FROM mtcars1 
    UNION ALL 
    Select * FROM mtcars2") 


# Error in .local(conn, statement, ...) : 
# Unable to execute statement 'CREATE TABLE mt_1_2 AS 
# Select * FROM mtcars1 
# UNION ALL 
# Select * FROM mtcars2'. 
# Server says 'syntax error, unexpected SCOLON, expecting WITH in: "create table mt_1_2 as 
# select * from mtcars1 
# union all 
# select * from mtcars2" 
# ' [#42000]. 
+0

Последний запрос должен быть: '' '' 'CREATE TABLE mt_1_2 AS SELECT * FROM mtcars1 UNION ALL Выберите * FROM mtcars2 С ДАННЫМИ '' ' –

+0

Ах. Большое спасибо, Ханнес. – charlie

+0

hi, 'MonetDBLite' (на CRAN) теперь заменяет« MonetDB.R »и запускается встроенный (например,« RSQLite'). более подробно см. https://github.com/hannesmuehleisen/MonetDBLite/blob/master/README.md –

ответ

1

Вы можете придерживаться dplyr и использовать rbind_list

library(MonetDB.R) 
library(MonetDBLite) 
library(dplyr) 

mtcars1 <- mtcars[, -11] # create 2 slightly different versions of mtcars 
mtcars2 <- mtcars[, -10] 

## Reduce size 
mtcars1 <- mtcars1[rep(seq(nrow(mtcars1)), 10000), ] 
mtcars2 <- mtcars2[rep(seq(nrow(mtcars2)), 10000), ] 

### Check size 
nrow(mtcars1) 
## [1] 320000 

nrow(mtcars2) 
## [1] 320000 

### 
dbdir <- tempdir() ## create a temporary directory 
con <- dbConnect(MonetDB.R(), embedded = dbdir) 

### 
dbWriteTable(con, name = "mtcars1", value = mtcars1) 
dbWriteTable(con, name = "mtcars2", value = mtcars2) 

dbListTables(con) 

### 
ms <- src_monetdb(embedded = dbdir) # create a dplyr::tbl version tables 
mt1 <- tbl(ms, "mtcars1") 
mt2 <- tbl(ms, "mtcars2") 

### You need to add `n = -1` to `as.data.frame` to retrieve all rows 
dbWriteTable(con, "mt_1_2", rbind_list(as.data.frame(mt1, n = -1), 
             as.data.frame(mt2, n = -1))) 

### 
dbGetQuery(con, "SELECT COUNT(*) FROM mt_1_2") 
##  L1 
## 1 640000 
+0

Большое спасибо, dickoa. Это работает. Более 2 таблиц вернули сообщение об ошибке, неспособное принудительно выполнить привязку к фреймворку данных. Но он смог пропустить данные по 2 кадра за раз. В конце концов ударил стену, хотя, когда я выбежал из ОЗУ, пытаясь объединить две из четырехлетних таблиц. Каждый из них имел около 60 миллионов наблюдений и 120 переменных. У меня 64G памяти на моей машине, и я думал, что этого будет достаточно. Но явно нет. Я пытаюсь выяснить, что с этим делать. – charlie

 Смежные вопросы

  • Нет связанных вопросов^_^