2011-01-18 14 views
6

Ho una serie di misurazioni effettuate regolarmente, ma alcuni sono mancanti:Come si combinano due vettori di lunghezza diversa in R

 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 

Ho una funzione che sta per elaborare i valori e in grado di gestire i valori mancanti , ma la riga deve essere lì in modo da sto generando una matrice che ha una riga per ogni minuto in questo modo:

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

ora ho una riga per ogni minuto dell'ora, ma ho bisogno di unire i dati . Ho provato qualcosa del genere ma non sono riuscito a farlo bene:

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 .. 
} 

ma ricevo solo errori e avvisi. Sto andando in giro il problema nel modo giusto? Voglio davvero una matrice "completa" con valori al minuto in quanto ci saranno molte funzioni diverse che verranno eseguite delle letture e semplicemente renderà più semplice la loro implementazione se possono supporre che sia tutto lì.

+0

cercare di fornire almeno un esempio riproducibile come Gavin vi ha mostrato. Inoltre, ho la sensazione che tu stia rendendo le cose troppo complesse. Non riesco a pensare a un caso in cui devi aggiungere NA per far funzionare una funzione. –

+0

Vedere FAQ n. 13 nello zoo FAQ: http://cran.r-project.org/web/packages/zoo/vignettes/zoo-faq.pdf –

risposta

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)) 

due approcci possono essere utilizzati, la prima via 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 

Il secondo è tramite una variabile indicatore ottenuta impiegando %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 versione di unione è fortemente preferito, ma ha bisogno di un po 'di lavoro. La soluzione %in% funziona qui solo perché i dati sono in ordine di orario sia in DF e full, quindi il mio precedente "preferito". Tuttavia, è facile ottenere/garantire i due oggetti in ordine cronologico, quindi entrambi gli approcci richiedono un po 'di finezza per funzionare. Siamo in grado di modificare l'approccio %in% per ottenere entrambe le variabili in ordine (ripartire 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

Le grandi menti pensano allo stesso modo ... :-) –

+2

In effetti .. . (+1) "The Joris-Gavin Mutual Appreciation Society" –

+1

La seconda soluzione dipende dall'ordine delle righe per essere corretto. La versione leggermente migliore sarebbe 'want <- match (DF $ measurement_date, full $ measurement_date)'. Ma ci sono così tante insidie ​​(id duplicati, ecc.) Che la soluzione di fusione è fortemente preferita. –

6

Nella vostra funzione, come numerico (candiated) dovrebbe essere as.numeric (candidato). C'è anche una parentesi mancante. Non ho idea di cosa esattamente stai cercando di ottenere nella tua funzione, ma mi sembra orrendamente complesso.

Prova

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

Questo dovrebbe darvi qualcosa su cui lavorare.

Problemi correlati