2011-01-18 15 views
6

Tengo un conjunto de mediciones realizadas con regularidad, pero faltan algunos:¿Cómo combino dos vectores de diferente longitud en I

 measurement_date value 
1 2011-01-17 13:00:00  5 
2 2011-01-17 13:04:00  5 
3 2011-01-17 13:08:00  7 
4 2011-01-17 13:12:00  8 
5 2011-01-17 13:16:00  4 
6 2011-01-17 13:24:00  6 
7 2011-01-17 13:28:00  5 
8 2011-01-17 13:32:00  6 
9 2011-01-17 13:36:00  9 
10 2011-01-17 13:40:00  8 
11 2011-01-17 13:44:00  6 
12 2011-01-17 13:48:00  6 
13 2011-01-17 13:52:00  4 
14 2011-01-17 13:56:00  6 

Tengo una función que va a procesar los valores y puede manejar los valores perdidos , pero la fila tiene que estar allí, así que estoy generando una matriz que tiene una fila por cada minuto de esta manera:

times <- timeSequence(from=.., length=60, by="min") 

ahora tengo una fila por cada minuto de la hora pero necesito para combinar los datos . Intenté algo como esto pero no pude hacerlo bien:

lapply(times, function(time) { 
    n <- as.numeric(time) 
    v <- Position(function(candidate) { 
     y <- as.numeric(candiated) 
     n == y 
    } 

    .. insert the value into the row here .. 
} 

pero solo recibo errores y advertencias. ¿Estoy dando la vuelta al problema de la manera correcta? Realmente quiero una matriz "completa" con valores por minuto, ya que habrá muchas funciones diferentes que se ejecutarán de las lecturas y simplemente hace que sea más fácil implementarlas si pueden suponer que todo está allí.

+0

tratar de proporcionar al menos un ejemplo reproducible Gavin se mostró. Además, tengo la sensación de que estás haciendo las cosas demasiado complejas. No puedo pensar en un caso en el que deba agregar NA para que una función funcione. –

+0

Ver Preguntas frecuentes # 13 en el zoológico Preguntas frecuentes: http://cran.r-project.org/web/packages/zoo/vignettes/zoo-faq.pdf –

Respuesta

8
DF <- data.frame(measurement_date = seq(as.POSIXct("2011-01-17 13:00:00"), 
             as.POSIXct("2011-01-17 13:56:00"), 
             by = "mins")[seq(1, 57, by = 4)][-6], 
       value = c(5,5,7,8,4,6,5,6,9,8,6,6,4,6)) 
full <- data.frame(measurement_date = seq(as.POSIXct("2011-01-17 13:00:00"), 
              by = "mins", length = 60), 
        value = rep(NA, 60)) 

dos enfoques pueden ser utilizados, la primera vía merge:

> v1 <- merge(full, DF, by.x = 1, by.y = 1, all = TRUE)[, c(1,3)] 
> names(v1)[2] <- "value" ## I only reset this to pass all.equal later 
> head(v1) 
    measurement_date value 
1 2011-01-17 13:00:00  5 
2 2011-01-17 13:01:00 NA 
3 2011-01-17 13:02:00 NA 
4 2011-01-17 13:03:00 NA 
5 2011-01-17 13:04:00  5 
6 2011-01-17 13:05:00 NA 

La segunda es a través de un indicador variable derivada usando %in%:

> want <- full$measurement_date %in% DF$measurement_date 
> full[want, "value"] <- DF[, "value"] 
> head(full) 
    measurement_date value 
1 2011-01-17 13:00:00  5 
2 2011-01-17 13:01:00 NA 
3 2011-01-17 13:02:00 NA 
4 2011-01-17 13:03:00 NA 
5 2011-01-17 13:04:00  5 
6 2011-01-17 13:05:00 NA 
> all.equal(v1, full) 
[1] TRUE 

La versión de combinación es fuertemente preferido, pero necesita un poco de trabajo. La solución %in% solo funciona aquí porque los datos están en orden de tiempo tanto en DF como en full, de ahí mi anterior "preferencia". Sin embargo, es fácil obtener/asegurar los dos objetos en orden temporal, por lo que ambos enfoques requieren un poco de finura para funcionar. Podemos modificar el enfoque %in% para conseguir ambas variables en orden (a partir de cero con full):

full2 <- data.frame(measurement_date = seq(as.POSIXct("2011-01-17 13:00:00"), 
              by = "mins", length = 60), 
        value = rep(NA, 60)) 
full2 <- full2[order(full2[,1]), ] ## get full2 in order 
DF2 <- DF[order(DF[,1]), ]   ## get DF in order 
want <- full$measurement_date %in% DF$measurement_date 
full2[want, "value"] <- DF2[, "value"] 

>  all.equal(full, full2) 
[1] TRUE 
>  all.equal(full2, v1) 
[1] TRUE 
> 
+1

Las mentes geniales piensan igual ... :-) –

+2

Indeed .. . (+1) "Sociedad de Aprecio Mutua Joris-Gavin" –

+1

La segunda solución depende del orden de las filas para ser correcta. Una versión ligeramente mejor sería 'want <- match (DF $ measurement_date, full $ measurement_date)'. Pero hay tantas trampas (identificaciones duplicadas, etc.) que la solución de fusión es muy preferida. –

6

En su función, as.numeric (candiated) debe ser as.numeric (candidate). También hay un soporte faltante. No tengo idea de qué es exactamente lo que estás tratando de lograr en tu función, pero me parece horrendo y complejo.

Trate

merge(Data,times,by.x=1,by.y=1,all.y=T) 

Esto debe darle algo con que trabajar.

Cuestiones relacionadas