如何在R中使用data.table进行基本的左外连接?

时间:2011-08-17 09:30:30

标签: sql r data.table

我有a和b的data.table,我已将其分区为below,其中b< .5和above与b> 0.5:

DT = data.table(a=as.integer(c(1,1,2,2,3,3)), b=c(0,0,0,1,1,1))
above = DT[DT$b > .5]
below = DT[DT$b < .5, list(a=a)]

我想在abovebelow之间进行左外连接:对于a中的每个above,计算below中的行数}。这相当于SQL中的以下内容:

with dt as (select 1 as a, 0 as b union select 1, 0 union select 2, 0 union select 2, 1 union select 3, 1 union select 3, 1),
  above as (select a, b from dt where b > .5),
  below as (select a, b from dt where b < .5)
select above.a, count(below.a) from above left outer join below on (above.a = below.a) group by above.a;
 a | count 
---+-------
 3 |     0
 2 |     1
(2 rows)

如何使用data.tables完成同样的事情?这是我到目前为止所尝试的:

> key(below) = 'a'
> below[above, list(count=length(b))]
     a count
[1,] 2     1
[2,] 3     1
[3,] 3     1
> below[above, list(count=length(b)), by=a]
Error in eval(expr, envir, enclos) : object 'b' not found
> below[, list(count=length(a)), by=a][above]
     a count b
[1,] 2     1 1
[2,] 3    NA 1
[3,] 3    NA 1

我还应该更具体一点,因为我已经尝试了merge但是这会打击我系统上的内存(数据集只占我内存的20%左右)。

4 个答案:

答案 0 :(得分:4)

由于您似乎在使用包data.table:请检查?merge.data.table。 我没有用它,但看起来这可能会做你想要的:

merge(above, below, by="a", all.x=TRUE, all.y=FALSE)

答案 1 :(得分:4)

看看这是否给你一些有用的东西。您的示例太稀疏,无法告诉我您想要的内容,但它似乎可能是above$a中值below$a的列表。{/ 1}}

table(above$a[above$a %in% below$a])

如果您还希望反转...值不在below中,那么这样就可以了:

table(above$a[!above$a %in% below$a])

你可以连接它们:

> c(table(above$a[above$a %in% below$a]),table(above$a[!above$a %in% below$a]) )
2 3 
1 2

通常table%in%的占地面积相当小而且速度很快。

答案 2 :(得分:2)

我认为这更容易:

setkey(above,a)
setkey(below,a)

左外连接:

above[below, .N]

定期加入:

above[below, .N, nomatch=0]

带有计数的完全外部联接:

merge(above,below, all=T)[,.N, by=a]

答案 3 :(得分:1)

我最终找到了一种用data.table做到这一点的方法,虽然YMMV:

,但我认为这比DWin table更自然。
result = below[, list(count=length(b)), by=a]
key(result) = 'a'
result = result[J(unique(above$a))]
result$count[is.na(result$count)] = 0
但是,我不知道这是否会更紧凑。我特别希望能够做result = below[J(unique(above$a)), list(count=length(b))]这样的事情,但这不起作用。