3

我有一个 a 和 b 的 data.table,我below用 b < .5 和aboveb > .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)]

我想在aboveand之间做一个左外连接below:对于每个ain above,计算 in 的行数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

4 回答 4

4

由于您似乎正在使用包data.table:检查?merge.data.table。我没有使用它,但它似乎可以满足您的需求:

merge(above, below, by="a", all.x=TRUE, all.y=FALSE)
于 2011-08-17T09:53:25.170 回答
4

看看这是否给你一些有用的东西。您的示例太稀疏,无法让我知道您想要什么,但似乎它可能是一个列表,其中的值above$a也在below$a

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

如果您还想要 converse ... 值不在 中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%运行在相当小的占地面积内,而且速度很快。

于 2011-08-17T20:01:32.510 回答
2

我认为这更容易:

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

左外连接:

above[below, .N]

常规加入:

above[below, .N, nomatch=0]

全外连接计数:

merge(above,below, all=T)[,.N, by=a]
于 2014-04-27T14:22:19.877 回答
1

我最终找到了一种方法来做到这一点data.table,我觉得这比 DWin 更自然table,尽管 YMMV:

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))],但这不起作用。

于 2011-08-18T00:28:16.113 回答