Ifelse mit ddply transformieren

Ich versuche es zu benutzenddply mittransform um eine neue Variable zu füllen (summary_Date) in einem Datenrahmen mit VariablenID undDate. Der Wert der Variablen wird basierend auf der Länge des zu bewertenden Teils ausgewähltifelse:

Wenn es weniger als fünf Beobachtungen für einen Ausweis in einem bestimmten Monat gibt, möchte ich habensummary_Date berechnet werden, indem das Datum auf den nächsten Monat gerundet wird (mitround_date ab paketlubridate); Wenn es mehr als fünf Beobachtungen für einen Ausweis in einem bestimmten Monat gibt, möchte ich diesummary_Date einfach seinDate.

require(plyr)
require(lubridate)

test.df <- structure(
  list(ID = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1, 1, 1
                , 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,2, 2, 2, 2, 2, 2, 2, 2)
       , Date = structure(c(-247320000, -246196800, -245073600, -243864000
                            , -242654400, -241444800, -126273600, -123595200
                            , -121176000, -118497600, 1359385200, 1359388800
                            , 1359392400, 1359396000, 1359399600, 1359403200
                            , 1359406800, 1359410400, 1359414000, 1359417600
                            , 55598400, 56116800, 58881600, 62078400, 64756800
                            , 67348800, 69854400, 72964800, 76161600, 79012800
                            , 1358589600, 1358676000, 1358762400, 1358848800
                            , 1358935200, 1359021600, 1359108000, 1359194400
                            , 1359280800, 1359367200), tzone = "GMT"
                          , class = c("POSIXct", "POSIXt"))
       , Val=rnorm(40))
  , .Names = c("ID", "Date", "Val"), row.names = c(NA, 40L)
  , class = "data.frame")

test.df <- ddply(test.df, .(ID, floor_date(Date, "month")), transform
                 , summary_Date=as.POSIXct(ifelse(length(ID)<5
                                                  , round_date(Date, "month")
                                                  ,Date)
                                           , origin="1970-01-01 00:00.00"
                                           , tz="GMT")
                 # Included length_x to easily see the length of the subset
                 , length_x = length(ID))

head(test.df,5)
#   floor_date(Date, "month") ID                Date        Val summary_Date length_x
# 1                1962-03-01  1 1962-03-01 12:00:00 -0.1037988   1962-03-01        3
# 2                1962-03-01  1 1962-03-14 12:00:00  0.2923056   1962-03-01        3
# 3                1962-03-01  1 1962-03-27 12:00:00  0.4435410   1962-03-01        3
# 4                1962-04-01  1 1962-04-10 12:00:00  0.1159164   1962-04-01        2
# 5                1962-04-01  1 1962-04-24 12:00:00  2.9824075   1962-04-01        2

Dasifelse Die Anweisung scheint zu funktionieren, aber der Wert in 'summary_Date' scheint der erste Wert zu sein, der für die Teilmenge berechnet wird, an der die Transformation arbeitet, und nicht der zeilenspezifische Wert. Zum Beispiel in Zeile 3,summary_Date sollte sein1962-04-01 weil das Datum1962-03-27 12:00:00' sollte aufgerundet werden (da die Teilmenge weniger als fünf Zeilen enthält), sondern der erste berechnete Wert vonsummary_Date (1962-03-01) wird in allen Zeilen dieser Teilmenge wiederholt.

BEARBEITEN: Ich war inspiriert von Ricardos Antwort mitdata.table in zwei schritten probieren mitddply. Es funktioniert auch:

test.df <- ddply(test.df, .(ID, floor_date(Date, "month")), transform
                 , length_x = length(ID))

test.df <- ddply(test.df, .(ID, floor_date(Date, "month")), transform
                 , summary_Date=as.POSIXct(ifelse(length_x<5
                                                  , round_date(Date, "month")
                                                  ,Date)
                                           , origin="1970-01-01 00:00.00"
                                           , tz="GMT"))

head(test.df,5)[c(1,3:7)]
#   floor_date(Date, "month") ID                Date        Val length_x summary_Date
# 1                1962-03-01  1 1962-03-01 12:00:00 -0.1711212        3   1962-03-01
# 2                1962-03-01  1 1962-03-14 12:00:00 -0.1531571        3   1962-03-01
# 3                1962-03-01  1 1962-03-27 12:00:00  0.1256238        3   1962-04-01
# 4                1962-04-01  1 1962-04-10 12:00:00  1.4481225        2   1962-04-01
# 5                1962-04-01  1 1962-04-24 12:00:00 -0.6508731        2   1962-05-01

Antworten auf die Frage(2)

Ihre Antwort auf die Frage