2

SQL 側または R 側で、より多くの列を持つ既存のテーブルに data.frame を追加する簡単な方法はありますか? 欠落している列には、NA を入力する必要があります。テーブル 1 よりも多くの列を持つテーブル 2 を適切に処理する場合のボーナス ポイントは?

library(RSQLite)

# Create
db <- dbConnect( SQLite(), dbname="~/temp/test.sqlite" )

# Write test
set.seed(1)
n <- 1000
testDat <- data.frame(key=seq(n), x=runif(n),y=runif(n),g1=sample(letters[1:10],n,replace=TRUE),g2=rep(letters[1:10],each=n/10),g3=factor( sample(letters[1:10],n,replace=TRUE) ))
if(dbExistsTable(db,"test")) dbRemoveTable(db,"test")
dbWriteTable( conn = db, name = "test", value = testDat, row.names=FALSE )
testDat2 <- data.frame( key=seq(n+1,n+100), x=runif(100) )
> dbWriteTable( conn = db, name="test", value = testDat2, row.names=FALSE, append=TRUE  )
[1] FALSE
Warning message:
In value[[3L]](cond) :
  RS-DBI driver: (error in statement: table test has 6 columns but 2 values were supplied)

このためのラッパーも想像できます。アルゴリズムは次のようになります。

  1. 既存の SQL テーブルから 1 行を読み取ります。
  2. その読み取りから列名を取得します。
  3. 含まれていない名前で列名を data.frame に追加します。不足を埋める。
  4. dbWriteTable は、data.frame が SQL テーブルと同じ列を持つようになりました。

これは、SQLite に変更可能なクラスがあるという事実によって単純化されています。しかし、車輪がすでに存在する場合は、車輪を再発明したくありません。

編集

明確にするためのメモ: これらのデータセットは大きいです。SQL データベースは約 30 GB になり、data.frame (実際にdata.tableは明白な理由により) は約 4 GB になります。したがって、SQL テーブルを R に読み込む必要があるソリューションは、初心者向けではありません。

別のアルゴリズムは、SQL でそれを行うことです。

  1. R data.frame を一時 SQL テーブルに書き込みます。
  2. そのテーブルをメイン SQL テーブルに追加する SQL マジック。
  3. 一時 SQL テーブルを削除します。
  4. 利益。
4

3 に答える 3

1

解決策の 1 つは、dbSendQuery を使用して 1 つのテーブルをたとえば 1000 行単位で読み取り、それらを別のテーブルに追加する (必要な列を追加する) ことです。

res <- dbSendQuery(con, "SELECT * from tests")
while(!dbHasCompleted(res)) {
  data <- fetch(res, n = 1000);
  ### Put the data in the other table
}

単一の SQLite クエリでそれを行う方法もあります。追加する (NULL で埋める) 列がわかっている場合、SQL クエリは次のようになります。

INSERT INTO target_table SELECT col1,NULL,col2,col3,NULL,NULL,col4 FROM source_table
于 2013-11-10T08:27:44.837 に答える
0

rbind.fillfromplyrは、R 内からこの連結を行う優れた方法を提供します。

require(plyr)
X <- rbind.fill(testDat, stDat2)

ただし、接続側で追加を行いたいように見えるため、これがあなたの質問に完全に答えているかどうかはわかりません。

于 2013-11-09T17:37:15.303 に答える