我有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)]
我想在above
和below
之间进行左外连接:对于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%左右)。
答案 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:
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))]
这样的事情,但这不起作用。