2010-08-06 7 views
4

J'ai une trame de données contenant des informations sur les options comme celui-ciR vérification des paires de lignes dans une trame de données

> chData 
myIdx strike_price  date  exdate cp_flag strike_price return 
1 8355342  605000 1996-04-02 1996-05-18  P  605000 0.002340 
2 8355433  605000 1996-04-02 1996-05-18  C  605000 0.002340 
3 8356541  605000 1996-04-09 1996-05-18  P  605000 -0.003182 
4 8356629  605000 1996-04-09 1996-05-18  C  605000 -0.003182 
5 8358033  605000 1996-04-16 1996-05-18  P  605000 0.003907 
6 8358119  605000 1996-04-16 1996-05-18  C  605000 0.003907 
7 8359391  605000 1996-04-23 1996-05-18  P  605000 0.005695 

où cp_flag signifie qu'une certaine option est soit un achat ou de vente. Quel est un moyen de s'assurer que pour chaque date, il y a à la fois un appel et un put, et de laisser tomber les lignes pour lesquelles cela n'existe pas? Je peux le faire avec une boucle for, mais y a-t-il une manière plus intelligente?

Répondre

10

Obtenez les dates qui ont P et ceux qui ont de C, et l'utilisation entrecoupent pour trouver les dates qui ont à la fois.

keep_dates <- with(x, intersect(date[cp_flag=='P'], date[cp_flag=='C'])) 
# "1996-04-02" "1996-04-09" "1996-04-16" 

Conservez uniquement les lignes dont les dates apparaissent dans la zone keep_dates.

x[ x$date %in% keep_dates, ] 
# myIdx strike_price  date  exdate cp_flag strike_price.1 
# 8355342  605000 1996-04-02 1996-05-18  P   605000 
# 8355433  605000 1996-04-02 1996-05-18  C   605000 
# 8356541  605000 1996-04-09 1996-05-18  P   605000 
# 8356629  605000 1996-04-09 1996-05-18  C   605000 
# 8358033  605000 1996-04-16 1996-05-18  P   605000 
# 8358119  605000 1996-04-16 1996-05-18  C   605000 
+0

Élégant! J'aime beaucoup celui-ci. – Vince

0

est ici un moyen utilisant split et lapply:

> tmp <- lapply(split(d, list(d$date)), function(x) if(all(c('P', 'C') %in% x[, 5])) x) 
> do.call(rbind, tmp) 
      myIdx strike_price  date  exdate cp_flag strike_price return 
1996-05-18.1 8355342  605000 1996-04-02 1996-05-18  P  605000 0.002340 
1996-05-18.2 8355433  605000 1996-04-02 1996-05-18  C  605000 0.002340 
1996-05-18.3 8356541  605000 1996-04-09 1996-05-18  P  605000 -0.003182 
1996-05-18.4 8356629  605000 1996-04-09 1996-05-18  C  605000 -0.003182 
1996-05-18.5 8358033  605000 1996-04-16 1996-05-18  P  605000 0.003907 
1996-05-18.6 8358119  605000 1996-04-16 1996-05-18  C  605000 0.003907 
1996-05-18.7 8359391  605000 1996-04-23 1996-05-18  P  605000 0.005695 

Edit: Voici la version complète implicite de ma dernière réponse. J'ai tendance à penser dans les fonctions de base plutôt que dans le plyr ou le remodelage ... mais ces réponses semblent bonnes aussi.

+0

Je dois prendre des pilules folles ... 'lapply' +' split' est mieux fait avec juste 'tapply'. Mais la solution de Wch semble * beaucoup * plus propre. – Vince

1

Utilisation du package plyr:

> ddply(chData, "date", function(x) if(all(c("P","C") %in% x$cp_flag)) x) 
    myIdx strike_price  date  exdate cp_flag strike_price.1 return 
1 8355342  605000 1996-04-02 1996-05-18  P   605000 0.002340 
2 8355433  605000 1996-04-02 1996-05-18  C   605000 0.002340 
3 8356541  605000 1996-04-09 1996-05-18  P   605000 -0.003182 
4 8356629  605000 1996-04-09 1996-05-18  C   605000 -0.003182 
5 8358033  605000 1996-04-16 1996-05-18  P   605000 0.003907 
6 8358119  605000 1996-04-16 1996-05-18  C   605000 0.003907 
+0

Ce langage devient de plus en plus cryptique et non-intuitif, plus je lis à ce sujet. Qu'est-ce qu'un ddply plyr? – Karl

+0

@Karl, c'est un paquet, pas la langue "de base". – Vince

+0

Il semble juste cryptique à cause de la fonction là-bas. 'plyr' et ses fonctions sont vraiment * merveilleux. – JoFrhwld

1

Voici une approche reshape.

library(reshape) 
#Add a dummy value 
df$value <- 1 
check <- cast(df, myIdx + strike_price + date + exdate + strike_price + return ~ cp_flag) 

#take stock of what just happened 
summary(check) 

#use only complete cases. If you have NAs elsewhere, this will knock out those obs too 
check <- check[complete.cases(check),] 

#back to original form 
df.clean <- melt(check, id = 1:6) 
Questions connexes