Esta es mi primera publicación, así que me disculpo si no soy lo suficientemente específico.

Tengo una secuencia de meses y un marco de datos con aproximadamente 100 filas, cada una con un identificador único. Cada identificador está asociado con una fecha de inicio. Estoy tratando de calcular el número de meses desde el inicio para cada uno de estos identificadores únicos en cada mes de la secuencia. He intentado sin éxito escribir un bucle for para lograr esto.

Ejemplo a continuación:

# Build Example Data Frame #
x_example <- c("A","B","C","D","E")
y_example <- c("2013-10","2013-10","2014-04","2015-06","2014-01")
x_name <- "ID"
y_name <- "StartUp"
df_example <- data.frame(x_example,y_example)
names(df_example) <- c(x_name,y_name)

# Create Sequence of Months, Format to match Data Frame, Reverse for the For Loop #
base.date <- as.Date(c("2015-11-1"))
Months <- seq.Date(from = base.date , to = Sys.Date(), by = "month")
Months.1 <- format(Months, "%Y-%m")
Months.2 <- rev(Months.1)

# Create For Loop #
require(zoo)
for(i in seq_along(Months.2))
{
  for(j in 1:length(summary(as.factor(df_example$ID), maxsum = 100000)))
  {
   Active.Months <- 12 * as.numeric((as.yearmon(Months.2 - i) - as.yearmon(df_example$StartUp)))
  }
}

La idea detrás del ciclo for era que para cada registro en la secuencia Months.2, habría un cálculo del número de meses hasta ese registro (fecha del mes) desde el mes de inicio para cada uno de los identificadores únicos. Sin embargo, esto ha estado devolviendo el error:

Error en meses.2 - i: argumento no numérico para operador binario

No estoy seguro de cuál es la solución o si estoy usando el bucle for correctamente para esto.

¡Gracias de antemano por cualquier ayuda para resolver este problema!

Editar: Esto es lo que espero que sea mi resultado esperado (esto es solo una muestra, ya que hay más meses en la secuencia):

 ID Start Up Month 2015-11 2015-12 2015-12 2016-02 2016-03
1  A        2013-10      25      26      27      28      29
2  B        2013-10      25      26      27      28      29
3  C        2014-04      19      20      21      22      23
4  D        2015-06       5       6       7       8       9
5  E        2014-01      22      23      24      25      26
0
DW1 29 jul. 2016 a las 16:58

2 respuestas

La mejor respuesta

Una forma de hacerlo es usar primero as.yearmon del paquete zoo para convertir las fechas. Luego, simplemente iteramos durante meses y restamos de los de df_example,

library(zoo)

df_example$StartUp <- as.Date(as.yearmon(df_example$StartUp))
Months.2 <- as.Date(as.yearmon(Months.2))

df <- as.data.frame(sapply(Months.2, function(i) 
                    round(abs(difftime(df_example$StartUp, i, units = 'days')/30))))
names(df) <- Months.2
cbind(df_example, df)

#  ID StartUp 2016-07 2016-06 2016-05 2016-04 2016-03 2016-02 2016-01 2015-12 2015-11
#1  A 2013-10      33      32      31      30      29      28      27      26      25
#2  B 2013-10      33      32      31      30      29      28      27      26      25
#3  C 2014-04      27      26      25      24      23      22      21      20      19
#4  D 2015-06      13      12      11      10       9       8       7       6       5
#5  E 2014-01      30      29      28      27      26      25      24      23      22
1
Sotos 29 jul. 2016 a las 17:24
x_example <- c("A","B","C","D","E")
y_example <- c("2013-10","2013-10","2014-04","2015-06","2014-01")
y_example <- paste(y_example,"-01",sep = "")

# past on the "-01" because I want the later function to work. 

x_name <- "ID"
y_name <- "StartUp"
df_example <- data.frame(x_example,y_example)
names(df_example) <- c(x_name,y_name)


base.date <- as.Date(c("2015-11-01"))
Months <- seq.Date(from = base.date , to = Sys.Date(), by = "month")
Months.1 <- format(Months, "%Y-%m-%d")
Months.2 <- rev(Months.1)

monnb <- function(d) { lt <- as.POSIXlt(as.Date(d, origin="1900-01-01")); lt$year*12 + lt$mon } 
mondf <- function(d1, d2) {monnb(d2) - monnb(d1)}

NumofMonths <- abs(mondf(df_example[,2],Sys.Date()))

n = max(NumofMonths)

# sequence along the number of months and get the month count. 

monthcount <- (t(sapply(NumofMonths, function(x) pmax(seq((x-n+1),x, +1), 0) )))
monthcount <- data.frame(monthcount[,-(1:24)])
names(monthcount) <- Months.1

finalDataFrame <- cbind.data.frame(df_example,monthcount)

Aquí está su marco de datos final, que es la salida deseada que indicó:

  ID    StartUp 2015-11-01 2015-12-01 2016-01-01 2016-02-01 2016-03-01 2016-04-01 2016-05-01 2016-06-01 2016-07-01
1  A 2013-10-01         25         26         27         28         29         30         31         32         33
2  B 2013-10-01         25         26         27         28         29         30         31         32         33
3  C 2014-04-01         19         20         21         22         23         24         25         26         27
4  D 2015-06-01          5          6          7          8          9         10         11         12         13
5  E 2014-01-01         22         23         24         25         26         27         28         29         30

La idea general es que calculamos el número de meses y usamos la función de secuencia para crear un contador del número de meses hasta que obtengamos el mes actual.

0
Adam Warner 29 jul. 2016 a las 14:56