您好我想选择一组以数据表中的值为条件的值。
具体来说,我想选择按日期和id分组的所有列,其中所有正值都是e == 1
id date e logret
7 2011-07-29 1 -0.0272275211
7 2011-07-29 2 0.0034229025
7 2011-07-29 3 0.0042622177
8 2011-07-29 1 0.0035662770
8 2011-07-29 2 -0.0015268474
8 2011-07-29 3 0.0013333333
7 2011-07-30 1 0.0044444444
7 2011-07-30 2 -0.0001111111
7 2011-07-30 3 0.0013333333
此处将选择id 8和日期2011-07-29的所有元素以及日期2011-07-30的id 7的所有元素,因为e == 1的logret是> 0,因为第一个logret(其中e == 1)是< 0
答:
8 2011-07-29 1 0.0035662770
8 2011-07-29 2 -0.0015268474
8 2011-07-29 3 0.0013333333
7 2011-07-30 1 0.0044444444
7 2011-07-30 2 -0.0001111111
7 2011-07-30 3 0.0013333333
在SQL中我会使用某种subselect来实现这一点。我会:
1) Select the id and date where e=1 and logret > 0
2) Select * join on results of subselect
我认为data.table也可以这样做,但我发现在data.table术语中表达它很棘手。具体来说,我可以复制第1步,但不能在步骤2中执行连接部分。
pos <- DT[e==1][logret > 0]
但是无法将pos值加入我的DT
答案 0 :(得分:3)
它不漂亮,而且它不在data.table
中,但这似乎可以起作用:
# Recreate your data
df = read.table(header=TRUE, text="id date e logret
7 2011-07-29 1 -0.0272275211
7 2011-07-29 2 0.0034229025
7 2011-07-29 2 0.0042622177
8 2011-07-29 1 0.0035662770
8 2011-07-29 2 -0.0015268474
8 2011-07-29 3 0.0013333333")
df[which(df$id != df$id[which(df$e == 1 & df$logret < 0)]),]
# id date e logret
# 4 8 2011-07-29 1 0.003566277
# 5 8 2011-07-29 2 -0.001526847
# 6 8 2011-07-29 3 0.001333333
#
## Or the equivalent in "positive" terms
#
# df[which(df$id == df$id[which(df$e == 1 & df$logret > 0)]),]
刚刚开始(我还没有 1>} data.table
包的体验;它在我的“学习”列表中。这是一个可能的解决方案:
temp = split(df, df$date)
lapply(temp,
function(x)
x[which(x$id == x$id[which(x$e == 1 & x$logret > 0)]),])
# $`2011-07-29`
# id date e logret
# 4 8 2011-07-29 1 0.003566277
# 5 8 2011-07-29 2 -0.001526847
# 6 8 2011-07-29 3 0.001333333
#
# $`2011-07-30`
# id date e logret
# 7 7 2011-07-30 1 0.0044444444
# 8 7 2011-07-30 2 -0.0001111111
# 9 7 2011-07-30 3 0.0013333333
值得尝试merge
:
merge(df, df[which(df$e == 1 & df$logret > 0), c(1, 2)])
# id date e logret
# 1 7 2011-07-30 1 0.0044444444
# 2 7 2011-07-30 2 -0.0001111111
# 3 7 2011-07-30 3 0.0013333333
# 4 8 2011-07-29 1 0.0035662770
# 5 8 2011-07-29 2 -0.0015268474
# 6 8 2011-07-29 3 0.0013333333
答案 1 :(得分:2)
我已经解决了一轮问题:
pos <- DT[e==1][logret > 0, list(id,date)]
ans <- DT[J(pos$id,pos$date)];
有兴趣在data.table中听到更优雅的1行方式。
Matthew的编辑:
如果key(DT)
已经(id,date)
,那么一个班轮就是:
DT[DT[e==1 & logret>0, list(id,date)]]
那也应该更快。如果您可以依赖id
和date
作为DT
的前两列,则可以缩短为:
DT[DT[e==1 & logret>0]]