2017-10-13 3 views
0

J'ai une trame de données df qui ressemble à ceci:Comment séparer des lignes entières dans de nouvelles trames de données en utilisant les instructions if

Date   Company   MarketCap 
2000-01-31 Company one  1000 
2000-02-28 Company one  2000 
2000-03-31 Company one  3000 
2000-01-31 Company two  2500 
2000-02-28 Company two  3000 
2000-03-31 Company two  3500 
2000-01-31 Company three 1500 
2000-02-28 Company three 1800 
2000-03-31 Company three 1100 

je besoin d'une instruction if qui effectue les opérations suivantes:

If(df$MarketCap >= median(df$MarketCap){ 
    BigCap <- df[all the rows that have a market cap >= median(df$MarketCap) 
} 

Mettez en mots; Pour chaque ligne de df$MarketCap, je veux vérifier si les capitalisations boursières sont supérieures ou égales à la capitalisation boursière médiane de df$MarketCap. Toutes les lignes contenant des capitalisations boursières supérieures ou égales à la capitalisation boursière médiane de df$MarketCap devraient constituer une nouvelle trame de données, BigCap.

La nouvelle trame de données BigCap devrait donc ressembler à ceci:

BigCap:

Date   Company   MarketCap 
2000-02-28 Company one  2000 
2000-03-31 Company one  3000 
2000-01-31 Company two  2500 
2000-02-28 Company two  3000 
2000-03-31 Company two  3500 

Je me sens comme cela devrait être facile à acheive en utilisant une instruction if, mais je ne l'ai pas eu de succès jusqu'ici (pas en regardant des questions similaires à SO non plus). J'apprécie toute l'aide que je peux obtenir.

Notez, mon vrai df est beaucoup plus grand que l'exemple fourni ici, où j'ai 360 dates et plus de 2000 entreprises.

Répondre

2

J'aime la réponse de CPAK mais si vous avez besoin data.frames séparé, cela fonctionne:

df <- data.frame(date = rep(Sys.Date() - c(60,30,0), 3), comp = rep(1:3, each = 3), 
      cap = c(1000, 2000, 3000, 2500, 3000, 3500, 1500, 1800, 1100)) 

for (i in unique(as.character(df$date))) { 
    med <- median(df$cap[df$date == i]) 
    assign(paste0("smallCap", format(as.Date(i), "%b")), 
     df[df$date == i & df$cap < med, ]) 
    assign(paste0("bigCap", format(as.Date(i), "%b")), 
     df[df$date == i & df$cap >= med, ]) 
} 

EDIT: dans les commentaires, OP a demandé une trame de données pour un mois spécifique.

Pour un mois donné dans une année donnée, par exemple octobre 2017:

# first calculate median 
med <- median(df$cap[format(df$date, "%Y-%m") == "2017-10"]) 
# subset df 
BigCapOct <- df[format(df$date, "%Y-%m") == "2017-10" & df$cap >= med, ] 

Pour le mois d'Octobre toutes les années:

med <- median(df$cap[format(df$date, "%m") == "10"]) 
BigCapOct <- df[format(df$date, "%m") == "10" & df$cap >= med, ] 
+0

Je vais essayer de votre réponse pour voir si Je peux le faire fonctionner. Notez que j'ai maintenant édité ma question un peu, afin de la rendre plus facile à comprendre (et peut-être à résoudre) –

+0

Votre question éditée maintenant besoin seulement 'BigCap <- df [df $ MarketCap> = médian (df $ MarketCap, na .rm = T),] ' –

+0

Merci, ça marche :) J'étais certain que j'aurais besoin d'une déclaration if et/ou for. Et si, comme dans ma question initiale, je voulais seulement faire cela pour certaines dates. C'est-à-dire, je veux faire un BigCapJan pour tous les plafonds de marché en janvier qui est supérieur ou égal à la capitalisation boursière médiane pour janvier. Existe-t-il un moyen facile de l'implémenter dans votre solution? J'ai essayé d'utiliser 'BigCapJan <- df [df $ MarketCap [stri_detect_fixed (df $ Date," 2000-01 ")]> = médiane (df $ MarketCap [stri_detect_fixed (df $ Date," 2000-01 ") ], na.rm = T),] 'mais cela ne semble pas fonctionner. –

2

J'ai créé SmallCap et , qui est une liste de data.frames qui contiennent des observations qui sont < median(MarketCap) ou >= median(MarketCap). Chaque entrée de la liste est une date distincte.

library(dplyr) 
SmallCap <- df %>% 
      group_by(Date) %>% 
      filter(MarketCap < median(MarketCap)) %>% 
      split(.$Date) 

# $`1` 
# # A tibble: 1 x 3 
# # Groups: Date [1] 
     # Date  Company MarketCap 
     # <fctr>  <fctr>  <int> 
# 1 2000-01-31 Company_one  1000 

# $`2` 
# # A tibble: 1 x 3 
# # Groups: Date [1] 
     # Date  Company MarketCap 
     # <fctr>  <fctr>  <int> 
# 1 2000-02-28 Company_three  1800 

# $`3` 
# # A tibble: 1 x 3 
# # Groups: Date [1] 
     # Date  Company MarketCap 
     # <fctr>  <fctr>  <int> 
# 1 2000-03-31 Company_three  1100 

LargeCap <- df %>% 
     group_by(Date) %>% 
      filter(MarketCap >= median(MarketCap)) %>% 
      split(.$Date) 

# $`2000-01-31` 
# # A tibble: 2 x 3 
# # Groups: Date [1] 
     # Date  Company MarketCap 
     # <fctr>  <fctr>  <int> 
# 1 2000-01-31 Company_two  2500 
# 2 2000-01-31 Company_three  1500 

# $`2000-02-28` 
# # A tibble: 2 x 3 
# # Groups: Date [1] 
     # Date  Company MarketCap 
     # <fctr>  <fctr>  <int> 
# 1 2000-02-28 Company_one  2000 
# 2 2000-02-28 Company_two  3000 

# $`2000-03-31` 
# # A tibble: 2 x 3 
# # Groups: Date [1] 
     # Date  Company MarketCap 
     # <fctr>  <fctr>  <int> 
# 1 2000-03-31 Company_one  3000 
# 2 2000-03-31 Company_two  3500