2016-06-22 9 views
0

1つのデータテーブル(ましょう呼がAれる)ID番号が含まれます。を効率的条件で2つのデータテーブルを結合

ID 
3 
5 
12 
8 
... 

と別のテーブル(のはBを呼び出すせ)が含ま下限と上限とそのIDの名前テーブルAからID所与テーブルBに基づいて

ID_lower ID_upper  Name 
1   4   James 
5   7   Arthur 
8   11  Jacob 
12   13  Sarah 

ので、我々は、表Bよう

ID_lower <= ID <= ID upper 

の行に名前を見つけることによって、一致する名前を見つけることができると私が作成したいですAの行ごとに、私はIDがID_lower間にあるようなBの行を探しように、上記の例では、それは、私がループに使用

ID   Name 
3   James 
5   Arthur 
12   Sarah 
8   Jacob 
...   ... 

であろうように、IDと名前のテーブル、およびその行のID_upperを使用して名前に参加しました そこから。 しかし、この方法は少し遅かったです。 Rでそれを行うのは速い方法ですか?

答えて

1

あなたは二data.frame(B)とのルックアップテーブル作ることができます:あなたはあなたの最初のdata.frame(A)と、それを照会

lu <- do.call(rbind, 
       apply(B,1,function(x) 
        data.frame(ID=c(x[1]:x[2]),Name=x[3], row.names = NULL))) 

を:

A$Name <- lu[A$ID,"Name"] 
1

私はにfindInterval()を信じる

data.table::setDT(B)[, .(Name, ID = Map(`:`, ID_lower, ID_upper))] 
        [, .(ID = unlist(ID)), .(Name)][ID %in% A$ID] 

    Name ID 
1: James 3 
2: Arthur 5 
3: Sarah 12 
4: Jacob 8 
+0

Psidomは、あなたは私が投稿した結合が非エクイを使用して、より簡単な解決に興味があるかもしれません。乾杯。 – Arun

+1

@Arun私は今朝それをすべて探しています。しかし、それを働かせるように見えることはできません。デモとリンクをありがとう。 – Psidom

1

:あなたはこのdata.tableソリューションを試すことができます210は、ここでは理想的なアプローチであるかもしれない:

A[,Name:=B[findInterval(ID,ID_lower),Name]]; 
A; 
## ID Name 
## 1: 3 James 
## 2: 5 Arthur 
## 3: 12 Sarah 
## 4: 8 Jacob 

(1)BID_lowerでソートされ、(2)A$IDのすべての値をBで範囲でカバーされている場合にのみ正しいであろう。新しいnon-equiを使用して

2

が、これは簡単です、data.tableの現在の開発版に機能を結合します

require(data.table) # v1.9.7+ 
dt2[dt1, .(ID, Name), on=.(ID_lower <= ID, ID_upper >= ID)] 

はdevelのバージョンhereのインストール手順を参照してください。


dt1=fread('ID 
      3 
      5 
      12 
      8') 
dt2 = fread('ID_lower ID_upper  Name 
        1   4  James 
        5   7 Arthur 
        8  11  Jacob 
        12  13  Sarah') 
関連する問題