2017-05-11 6 views
0

Angenommen, Sie haben Daten wie die folgenden, in denen, wie Sie sehen können, der erste Tag des Monats mehrmals wiederholt wird (Hinweis die date Variable).Behalten Sie den ersten Tag des Monats, auch wenn es wiederholt wird in R

date  exdate strike_price  delta 
1: 1996-01-04 1997-06-21  500000 -0.094917 
2: 1996-01-04 1996-03-16  600000 0.768930 
3: 1996-01-04 1996-02-17  605000 -0.286091 
4: 1996-01-04 1996-12-21  600000 0.651049 
5: 1996-01-04 1996-03-16  540000 -0.040929 
6: 1996-01-04 1996-02-17  630000 -0.638877 
7: 1996-01-05 1996-02-17  440000 0.579155 
..... 
51: 1996-02-04 1997-06-21  500000 -0.094917 
52: 1996-02-04 1996-03-16  600000 0.768930 
53: 1996-02-04 1996-02-17  605000 -0.286091 
54: 1996-02-04 1996-12-21  600000 0.651049 
55: 1996-02-04 1996-03-16  540000 -0.040929 
56: 1996-02-04 1996-02-17  630000 -0.638877 
  1. Was ich versuche, für jeden Monat zu tun ist, alle ersten Tage der Beobachtungen zu halten, das heißt alle Beobachtungen von 1:6 in der Menge, bezogen auf die date Variable. Einfach gesagt; der erste Tag eines jeden Monats ist mehr als einmal da, und ich möchte sie alle behalten, während ich die Ruhetage des Monats außer Acht lasse.
  2. Ist es dann möglich, aus den übrigen Beobachtungen diejenigen zu wählen, die nach den Änderungen in Schritt 1 die ersten beiden frühesten expdate haben?

Das Datumsformat ist YYYY-mm-dd.

Bisher gelang es mir, nur einen der ersten Tage des Monats statt all dieser Tage zu behalten. Der Code, den ich verwende, ist dies, aber er liefert nicht das gewünschte Ergebnis:

setDT(df)[order(date), .(delta[which.min(date)], date[which.min(date)]), by = .(year(date), month(date))] 

Vielen Dank.

+0

Ist Ihr Datum Variable Klasse Date? Sie können 'str (dt)' verwenden, um zu überprüfen, und 'dt [, date: = as.Date (date)]', um es zu konvertieren, wenn es im Format Ihres Beispiels ist. Wenn dies nicht das Problem ist, sollten Sie ein Dataset erstellen, das das Problem reproduzieren kann, das Sie in einem Beispieldatensatz angeben, vielleicht dput (head (dt, 20)) und sehen, dass das Problem dort wiederholt wird. Die Antwort, die ich zur Verfügung gestellt habe, funktioniert ordnungsgemäß mit den Beispieldaten. – lmo

+0

alles ist 'as.Date'.Die Sache ist, weil ich Hunderte von verschiedenen Daten habe, die Reihenfolge von: Rang (exdate) <3 'berücksichtigt den Rang aller Exdaten des Datums und nicht pro" Gruppe "von Daten. –

+0

Das gilt wiederum nur ohne das 'by = Argument'. In 'dtNew [, .I [Rang (exdate) <3], bis = Datum]', 'Rang (exdate)' berechnet den Rang für jedes Datum separat. – lmo

Antwort

1

Es ist wahrscheinlich eine effizientere Antwort, aber dies funktioniert:

# if data table is not loaded 
library(data.table) 
# if dt is a data.frame 
setDT(dt) 

Dann wird der folgende Code produzieren, was Sie wollen.

dt[dt[, .(date=min(date)), by=.(month(date), year(date))][,.(date)], on="date"] 

Die Idee ist, die ursprüngliche data.table auf eine data.table mit einer einzigen Spalte das Mindestdatum für jeden Monat zu erhalten beitreten enthält. Das Argument i für die Datei data.table ist eine chained data.table, wobei der erste Link in der Kette eine datendatei mit drei Spalten mit dem Mindestdatum für Monat und Jahr zurückgibt und der zweite Link in der Kette die Variablen Monat und Jahr auf gib nur die Datumsvariable zurück. Diese data.table wird über das Argument on="date" mit der ursprünglichen data.table verknüpft.

Das gibt

  date  exdate strike_price  delta 
1: 1996-01-04 1997-06-21  500000 -0.094917 
2: 1996-01-04 1996-03-16  600000 0.768930 
3: 1996-01-04 1996-02-17  605000 -0.286091 
4: 1996-01-04 1996-12-21  600000 0.651049 
5: 1996-01-04 1996-03-16  540000 -0.040929 
6: 1996-01-04 1996-02-17  630000 -0.638877 
7: 1996-02-04 1997-06-21  500000 -0.094917 
8: 1996-02-04 1996-03-16  600000 0.768930 
9: 1996-02-04 1996-02-17  605000 -0.286091 
10: 1996-02-04 1996-12-21  600000 0.651049 
11: 1996-02-04 1996-03-16  540000 -0.040929 
12: 1996-02-04 1996-02-17  630000 -0.638877 

für den zweiten Schritt, die beiden untersten exdates unter den verbleibenden (nach Datum), könnten Sie diese Zeilen in zwei tun.

# save above data.table 
dtNew <- dt[dt[, .(date=min(date)), by=.(month(date), year(date))][,.(date)], on="date"] 
# merge on the rows of the data.table that have the two lowest exdates 
dtNew[dtNew[, .I[rank(exdate) < 3], by=date]$V1,] 

.I berechnet wird verwendet, um die Klassifizierungen zurück wird die Zeilennummer der ursprünglichen data.table (dtNew) und Rang verwendet.

Daten

dt <- 
structure(list(date = structure(c(9499, 9499, 9499, 9499, 9499, 
9499, 9500, 9530, 9530, 9530, 9530, 9530, 9530), class = "Date"), 
    exdate = c("1997-06-21", "1996-03-16", "1996-02-17", "1996-12-21", 
    "1996-03-16", "1996-02-17", "1996-02-17", "1997-06-21", "1996-03-16", 
    "1996-02-17", "1996-12-21", "1996-03-16", "1996-02-17"), 
    strike_price = c(500000L, 600000L, 605000L, 600000L, 540000L, 
    630000L, 440000L, 500000L, 600000L, 605000L, 600000L, 540000L, 
    630000L), delta = c(-0.094917, 0.76893, -0.286091, 0.651049, 
    -0.040929, -0.638877, 0.579155, -0.094917, 0.76893, -0.286091, 
    0.651049, -0.040929, -0.638877)), .Names = c("date", "exdate", 
"strike_price", "delta"), row.names = c(NA, -13L), class = c("data.table", 
"data.frame"), index = structure(integer(0), "`\`__date\``" = integer(0))) 
+0

Ich dachte so etwas wie ja! Vielen Dank. Haben Sie den zweiten Teil der Frage berücksichtigt, der etwas schwieriger ist? –

+0

Könnten Sie mir bitte den Teil am Ende erklären: 'on = "date"' weil es einen Fehler von unbenutztem Argument gibt –

+0

Es ist komisch; Obwohl ich es aktualisiert habe, bekomme ich denselben unbenutzten Argumentfehler. 'newdata <-DF [DF [,. (Datum = min (Datum)), von =. (Monat (Datum), Jahr (Datum))] [,. (Datum)], am =" Datum "]' –

Verwandte Themen