2011-01-18 27 views
6

Mam zestaw pomiarów przeprowadzonych regularnie, ale trochę brakuje:Jak połączyć dwa wektory o różnej długości w 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 

Mam funkcję, która będzie przetwarzać wartości i może obsłużyć brakujących wartości , ale rząd musi tam być, więc jestem generowania tablicę, która zawiera wiersz dla każdej chwili jak ta:

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

teraz mam wiersz dla każdej minucie godziny, ale trzeba scalić dane . Próbowałem czegoś takiego, ale nie mogłem tego naprawić:

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

, ale dostaję tylko błędy i ostrzeżenia. Czy omijam problem we właściwy sposób? Naprawdę chcę mieć "kompletną" tablicę z wartościami na minutę, ponieważ będzie wiele różnych funkcji, które będą uruchamiane z odczytów i ułatwi to ich implementację, jeśli będą mogły założyć, że wszystko tam jest.

+0

staramy się zapewnić co najmniej powtarzalną przykład jak Gavin pokazałem. Poza tym mam przeczucie, że robisz rzeczy zbyt skomplikowane. Nie mogę wymyślić przypadku, w którym musisz dodać NA, aby funkcja działała. –

+0

Zobacz FAQ # 13 w zoo FAQ: http://cran.r-project.org/web/packages/zoo/vignettes/zoo-faq.pdf –

Odpowiedz

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

dwie metody można zastosować pierwsze poprzez 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 

Drugi przez zmienną wskaźnika otrzymanych z wykorzystaniem %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 

Wersja scalania silnie preferowane, ale wymaga trochę pracy. Rozwiązanie %in% działa tutaj tylko dlatego, że dane są uporządkowane w kolejności zarówno w przypadku DF, jak i full, stąd moje wcześniejsze "preferowane". Łatwo jest jednak uzyskać/zapewnić dwa obiekty w porządku czasowym, więc oba podejścia wymagają trochę finezji. Możemy zmodyfikować podejście %in% zdobycia obu zmiennych w kolejności (zaczynając na nowo z 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

Wielkie umysły myślą podobnie ... :-) –

+2

Rzeczywiście ... (+1) "Towarzystwo wzajemnego uznania Joris-Gavin" –

+1

Drugie rozwiązanie zależy od kolejności wierszy. Nieco lepsza wersja to 'want <- match (DF $ date_date, full $ measurement_date)'. Ale jest tak wiele pułapek (duplikatów, itd.), Że rozwiązanie scalania jest zdecydowanie preferowane. –

6

W swojej funkcji, jak numeryczne (candiated) powinno być numeryczne (kandydat). Brak też wspornika. Nie mam zielonego pojęcia, co dokładnie chcesz osiągnąć w swojej funkcji, ale wydaje mi się to niezwykle skomplikowane.

Spróbuj

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

To powinno dać coś do pracy.

Powiązane problemy