Pregunta

HI Quiero seleccionar un grupo de valores condicionados en un valor en una tabla de datos.

Específicamente, me gustaría seleccionar todas las columnas agrupadas por fecha e ID para todos los valores positivos donde 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

Aquí todos los elementos para la ID 8 y la fecha 2011-07-29 y todos los elementos de ID 7 para la fecha 2011-07-30 se seleccionarán ya que la Logret para E== 1 es> 0 donde todos los elementos de ID 7El 2011-07-29 se ignoran desde la primera Logret (donde E== 1) es <0

ans:

   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    

En SQL, usaría algún tipo de subselección para lograr esto.Yo haría:

1) Select the id and date where e=1 and logret > 0
2) Select * join on results of subselect

Pienso en los datos. Tal vez puede hacer esto, pero me resulta difícil expresarlo en los términos de datos.Específicamente, puedo replicar el Paso 1, pero no puedo hacer la parte de unión en el Paso 2.

pos <- DT[e==1][logret > 0]

pero no puedo unir los valores de POS en mi DT

¿Fue útil?

Solución 2

Lo he solucionado en una ronda de camino:

pos <- DT[e==1][logret > 0, list(id,date)]
ans <- DT[J(pos$id,pos$date)];

estaría interesado en escuchar cualquier forma más elegante de 1 línea de hacerlo en datos. Table.


Editar desde Matthew:

Si GreenacodicEtGode es ya key(DT), entonces un forro sería:

DT[DT[e==1 & logret>0, list(id,date)]]

y eso también debería ser más rápido.Si puede confiar en (id,date) y id, siendo las primeras 2 columnas de date, se puede acortar a:

DT[DT[e==1 & logret>0]]

Otros consejos

No es bonita, y no está en data.table, pero esto parece que funcionaría:

# 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)]),]

Actualización basada en comentarios y nuevos datos de muestra

Justo en la parte superior de mi cabeza (no he tenido ninguna experiencia con el paquete data.table; Está en mi lista de "Aprender").Aquí hay una posible solución:

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

Actualización 2

También vale la pena intentarlo 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top