Question

Bonjour, je souhaite sélectionner un groupe de valeurs conditionnées par une valeur dans un tableau de données.

Plus précisément, je voudrais sélectionner toutes les colonnes regroupées par date et identifiant pour toutes les valeurs positives où 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

ici, tous les éléments pour l'identifiant 8 et la date 2011-07-29 et tous les éléments de l'identifiant 7 pour la date 2011-07-30 seront sélectionnés puisque le logret pour e == 1 est > 0 alors que tous les éléments de l'identifiant 7 en 2011- 07-29 sont ignorés puisque le premier logret (où e==1) est < 0

Réponse :

   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, j'utiliserais une sorte de sous-sélection pour y parvenir.Je voudrais :

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

Je pense que data.table peut le faire aussi, mais je trouve difficile de l'exprimer en termes data.table.Plus précisément, je peux reproduire l'étape 1, mais je ne peux pas effectuer la partie jointure à l'étape 2.

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

Mais je ne peux pas joindre les valeurs pos dans mon DT

Était-ce utile?

La solution 2

Je l'ai résolu de manière détournée :

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

serait intéressé d'entendre des façons plus élégantes de le faire sur une ligne dans data.table.


EDIT de Matthieu :

Si key(DT) est déjà (id,date) alors une seule ligne serait :

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

et cela devrait aussi être plus rapide.Si tu peux compter sur id et date étant les 2 premières colonnes de DT, alors il peut être raccourci en :

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

Autres conseils

Ce n'est pas joli, et ce n'est pas dans data.table, mais cela semble fonctionner :

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

Mise à jour basée sur les commentaires et les nouveaux exemples de données

Juste du haut de ma tête (je n'ai pas eu n'importe lequel expérience avec le data.table emballer;c'est sur ma liste "à apprendre").Voici une solution possible :

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

Mise à jour 2

Cela vaut également la peine d'essayer 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top