5

複数の基準で 2 つの data.frames の交差に基づいてバイナリ ベクトルを設定しようとしています。

コードは動作していますが、バイナリ ベクトルを取得するためだけにメモリが過剰だと感じています。

コードを完全なデータ (40mm 以上の行) に適用すると。記憶障害が発生し始めます。

ベクトルを生成する簡単な方法はありますか?

以下にいくつかのサンプル データを示します (たとえば、サブ サンプルにはフル サンプルの観測のみが含まれます)。

ob1_1 <- as.data.frame(cbind(c(1999),c("111","222","666","777")),stringsAsFactors=FALSE)
ob2_1 <- as.data.frame(cbind(c(2000),c("111","333","555","777")),stringsAsFactors=FALSE)
ob3_1 <- as.data.frame(cbind(c(2001),c("111","222","333","777")),stringsAsFactors=FALSE)
ob4_1 <- as.data.frame(cbind(c(2002),c("111","444","555","777")),stringsAsFactors=FALSE)

full_sample <-  rbind(ob1_1,ob2_1,ob3_1,ob4_1)
colnames(full_sample) <- c("yr","ID")

ob1_2 <- as.data.frame(cbind(c(1999),c("111","222","777")),stringsAsFactors=FALSE)
ob2_2 <- as.data.frame(cbind(c(2000),c("333")),stringsAsFactors=FALSE)
ob3_2 <- as.data.frame(cbind(c(2001),c("888")),stringsAsFactors=FALSE)
ob4_2 <- as.data.frame(cbind(c(2002),c("111","444","555","777")),stringsAsFactors=FALSE)

sub_sample <-  rbind(ob1_2,ob2_2,ob3_2,ob4_2)
colnames(sub_sample) <- c("yr","ID")

ここに私の作業コードがあります:

q_intersect <- ""
q_intersect <- paste(q_intersect , "select       a.yr, a.ID       ", sep=" ")
q_intersect <- paste(q_intersect , "from         full_sample a  ", sep=" ")
q_intersect <- paste(q_intersect , "intersect                     ", sep=" ")
q_intersect <- paste(q_intersect , "select       b.yr, b.ID       ", sep=" ")
q_intersect <- paste(q_intersect , "from         sub_sample b  ", sep=" ")
q_intersect <- trim(gsub(" {2,}", " ", q_intersect ))

intersect_temp <- cbind(sqldf(q_intersect ),1)
colnames(intersect_temp ) <- c("yr","ID","in_both")

q_expand <- ""
q_expand <- paste(q_expand , "select       in_both            ", sep=" ")
q_expand <- paste(q_expand , "from         full_sample a      ", sep=" ")
q_expand <- paste(q_expand , "left join    intersect_temp  b  ", sep=" ")
q_expand <- paste(q_expand , "on           a.yr=b.yr          ", sep=" ")
q_expand <- paste(q_expand , "and          a.ID=b.ID          ", sep=" ")
q_expand <- trim(gsub(" {2,}", " ", q_expand ))

solution <- as.integer(sqldf(q_expand)[,1])
solution [is.na(solution )] <- 0 

助けてくれてありがとう!

4

2 に答える 2

4

あなたが達成しようとしていることは完全には明らかではありませんが、このようなことはもっと簡単になると思います.

library(data.table)
fullDT <- data.table(full_sample, key=c("yr", "ID"))
subDT  <- data.table(sub_sample,  key=c("yr", "ID"))

fullDT[ , intersect := 0L]
fullDT[subDT, intersect := 1, nomatch=0]

keyそれぞれdata.tableの を交差させたい列に設定するという考え方です。呼び出すfull[sub], nomatch=0]と、内部結合が取得され、それらの値のみが に設定され1ます。内部結合で識別されない値は、0前の行で設定されているようにそのまま残されます。

fullDT
#        yr  ID intersect
#   1: 1999 111         1
#   2: 1999 222         1
#   3: 1999 666         0
#   4: 1999 777         1
#   5: 2000 111         0
#   6: 2000 333         1
#   7: 2000 555         0
#   8: 2000 777         0
#   9: 2001 111         0
#  10: 2001 222         0
#  11: 2001 333         0
#  12: 2001 777         0
#  13: 2002 111         1
#  14: 2002 444         1
#  15: 2002 555         1
#  16: 2002 777         1
于 2013-03-24T05:03:01.470 に答える
2

より単純な SQL出力内の特定の行に、対応する行が一致する行があるfull_sample場合は 1 が含まれ、そうでない場合は 0 が含ま れるように、同じ数の行を持つ 1 列のデータ フレームを作成したいと考えています。 full_samplesub_sample

その場合、以下に示すように、複数の SQL ステートメントを 1 つの単純な SQL ステートメントにまとめることができます。左結合により、 のすべての行が確実にfull_sample含まれ、自然結合により、2 つの入力データ フレーム間で共通するすべての列名で結合が発生します。

sqldf("select s.yr is not null as solution 
       from full_sample f natural left join sub_sample s")

(ちなみに、これが示すように文字列リテラルは複数の行にまたがることができるので、複数の行を一緒に貼り付ける必要はありません。)

メモリ不足データベースdbname=sqldf はデフォルトでメモリ内データベースを使用しますが、メモリ不足データベースとして使用する引数を介してファイル名 (事前に存在する必要はありません) を指定できます。その場合、メモリによって制限されることはありません。

sqldf("select s.yr is not null as solution 
       from full_sample f natural left join sub_sample s", dbname = "mydb")

(場合によっては、インデックスを使用してパフォーマンスを向上させることもできます。例については、sqldf ホーム ページを参照してください。)

更新:より単純なSQLソリューションを追加

于 2013-03-24T05:31:11.290 に答える