一个数据表(让我们的呼叫为A)包含ID号:
ID
3
5
12
8
...
和另一个表(让我们称之为B)包含该下限和上限以及该ID的名称。
ID_lower ID_upper Name
1 4 James
5 7 Arthur
8 11 Jacob
12 13 Sarah
基于表B,给定表A中的ID,我们可以通过在表B中的行上查找名称找到匹配的名称,以便
ID_lower <= ID <= ID upper
我想创建一个ID和Name表,所以在上面的例子中,它将是
ID Name
3 James
5 Arthur
12 Sarah
8 Jacob
... ...
我用于循环,因此对于A的每一行,我在B中查找行,使得ID位于该行的ID_lower和ID_upper之间,并从那里加入名称。 但是,这种方法有点慢。在R中有没有快速的方法?
答案 0 :(得分:2)
在data.table的当前开发版本中使用新的non-equi
连接功能,这很简单:
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')
答案 1 :(得分:1)
您可以使用第二个data.frame(B)制作一个查找表:
lu <- do.call(rbind,
apply(B,1,function(x)
data.frame(ID=c(x[1]:x[2]),Name=x[3], row.names = NULL)))
然后用你的第一个data.frame(A)查询它:
A$Name <- lu[A$ID,"Name"]
答案 2 :(得分:1)
您可以尝试此data.table
解决方案:
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
答案 3 :(得分:1)
我相信ID_lower
A[,Name:=B[findInterval(ID,ID_lower),Name]];
A;
## ID Name
## 1: 3 James
## 2: 5 Arthur
## 3: 12 Sarah
## 4: 8 Jacob
可能是理想的方法:
B
只有当{1} ID_lower
按A$ID
排序并且(2)B
中的所有值都被var bob = "bob"
var joe = "joe"
var arr = [bob, joe]
arr[1] = "joseph"
print(joe)
// this returns "joe" and not sarah, because what happened is, arr is now equal to [bob, sarah]
中的范围所涵盖时,才会正确。< / p>