Pytanie:
Opóźnienie w zgrupowanych szeregach czasowych
Aren Cambre
2012-04-05 07:35:10 UTC
view on stackexchange narkive permalink

Mam kilkadziesiąt tysięcy obserwacji w szeregach czasowych, ale pogrupowanych według lokalizacji. Na przykład:

  lokalizacja data obserwacjaA obserwacjaB --------------------------------- ------ A 1-2010 22 12 A 2-2010 26 15 A 3-2010 45 16 A 4-2010 46 27 B 1-2010 167 48 B 2-2010 134 56 B 3-2010 201 53 B 4 -2010 207 42  

Chcę zobaczyć, czy obserwacja A miesiąca x ma jakikolwiek związek liniowy z miesiącem x + 1-ki observationB.

Poszukałem trochę informacji i znalazłem funkcję zoo , ale wydaje się, że nie ma sposobu opóźnienie według grupy. Więc jeśli użyję zoo i opóźnię obserwacjęB o 1 wiersz, otrzymam ostatnią obserwacjęB lokalizacji A jako pierwszą obserwacjęB lokalizacji B. Wolałbym, aby pierwsza obserwacjaB dowolnej lokalizacji była NA lub jakąś inną oczywistą wartością wskazującą „nie dotykaj tego wiersza”.

Myślę, że chodzi o to, czy jest na to wbudowany sposób w R? Jeśli nie, wyobrażam sobie, że mogę to zrobić za pomocą standardowej konstrukcji pętli. A może muszę w ogóle manipulować danymi?

Siedem odpowiedzi:
mpiktas
2012-04-05 08:18:34 UTC
view on stackexchange narkive permalink

Istnieje kilka sposobów uzyskania opóźnionej zmiennej w grupie. Przede wszystkim należy posortować dane, aby w każdej grupie czas był odpowiednio posortowany.

Najpierw utwórzmy przykładową ramkę data.frame:

  > set.seed (13) > dt <- data.frame (location = rep (letters [1: 2], każdy = 4), time = rep (1: 4, 2), var = rnorm (8)) > dt czas lokalizacji var1 a 1 0,55432692 a 2 -0,28027193 a 3 1,77516344 a 4 0,18732015 b 1 1,14252616 b 2 0,41552617 b 3 1.22950668 b 4 0.2366797  

Zdefiniuj naszą funkcję opóźnienia:

  lg <- function (x) c (NA, x [1: (length ( x) -1)])  
  1. Następnie można obliczyć opóźnienie zmiennej w grupie za pomocą tapply :

      > unlist (tapply (dt $ var, dt $ location, lg)) a1 a2 a3 a4 b1 b2 b3 b4 NA 0.5543269 -0.2802719 1.7751634 NA 1.1425261 0.4155261 1.2295066  
  2. Korzystanie z ddply z pakietu plyr”:

      > ddply (dt, ~ location, transform, lvar = lg (var)) czas lokalizacji var lvar1 a 1-0,1307015 NA2 a 2 -0,6365957 -0,13070153 a 3-0,6417577 -0,63659574 a 4 -1,5191950 -0,64175775 b 1 -1,6281638 NA6 b 2 0,8748671 -1,62816387 b 3 -1,3343222 0,87486718 b 4 1,5431753 -1,3343222 
  3. Szybsza wersja korzystająca z data.table z pakietu data.table

      > ddt <- data.table (dt) > ddt [, lvar: = lg (var), by = c ("lokalizacja")] czas lokalizacji var lvar [1,] a 1 -0,1307015 NA [2,] a 2 -0,6365957 -0,1307015 [3,] a 3 -0,6417577 -0,6365957 [4,] a 4 -1,5191950 -0,6417577
    [5,] b 1 -1,6281638 NA [6,] b 2 0,8748671 -1,6281638 [7,] b 3 -1,3343222 0,8748671 [8,] b 4 1,5431753 -1,3343222  
  4. Korzystanie z funkcji lag z pakietu plm”

      > pdt <- pdata.frame (dt) > lag (pdt $ var ) a-1 a-2 a-3 a-4 b-1 b-2 b-3 b-4 NA 0,5543269 -0,2802719 1,7751634 NA 1,1425261 0,4155261 1,2295066  
  5. Użycie funkcji lag z pakietu dplyr

      > dt% >% group_by (lokalizacja)% >% mutate (lvar = lag ( var)) Źródło: lokalna ramka danych [8 x 4] Grupy: lokalizacja lokalizacja czas var lvar1 a 1 0,5543269 NA2 a 2 -0,2802719 0,55432693 a 3 1,7751634 -0,28027194 a 4 0,1873201 1,77516345 b 1 1,1425261 NA6 b 2 0,4155261 1,14252617 b 3 1,2295066 0,41552618 b 4 0,2366797 1,2295066  

Ostatnie dwa podejścia wymagają konwersji z data.frame na inny obiekt, chociaż wtedy nie musisz martwić się o sortowanie. Moje osobiste preferencje to ostatnia opcja, która nie była dostępna podczas wstępnego pisania odpowiedzi.

Aktualizacja: Zmieniono kod data.table, aby odzwierciedlał rozwój pakietu data.table wskazany przez @Hibernating.

Aktualizacja 2: Dodano przykład dplyr .

Świetne wyjaśnienie!Czy istnieje pakiet / funkcja, która może obsługiwać nieregularnie rozmieszczone zgrupowane szeregi czasowe (panele) i niezrównoważone panele?
Wszystkie przykłady kodu będą działać dla niezrównoważonych paneli.W przypadku szeregów czasowych o nieregularnych odstępach pojęcie opóźnienia jest nieco skomplikowane, ponieważ może nie istnieć dla wszystkich grup.
Możesz zapytać o opóźnienia dla nieregularnych szeregów czasowych w przepełnieniu stosu.W statystykach tego typu pytania są teraz nie na temat.
Hibernating
2013-12-16 16:58:06 UTC
view on stackexchange narkive permalink

@ mpiktas Aby krótko wspomnieć o dwóch drobnych niedopatrzeniach w trzeciej wersji Twojej odpowiedzi. Po pierwsze, fraza „szybsza wersja” została wyraźnie pomyłka. Po drugie, w kodzie pominięto słowo „: =”. Naprawienie tego ostatniego naprawia pierwszą: =)

  biblioteka (data.table); ddt <- data.table (dt) f0<-function () plyr :: ddply (dt, ~ location, transform, lvar = lg (var)) f1<-function () ddt [, transform (.SD, lvar = lg (var)), by = c ("lokalizacja")] f2<-function () ddt [, lvar: = lg (var), by = lokalizacja] r0<-f0 (); r1<-f1 (); r2<-f2 (); all.equal (r0, r1, r2, check.attributes = FALSE) boxplot (microbenchmark :: f0 (), f1 (), f2 (), times = 1000L))  

enter image description here

Anirban Sengupta
2014-06-28 02:18:37 UTC
view on stackexchange narkive permalink

Zamiast przechodzić przez wszystkie tapply i dodatkowe kroki, jest szybszy sposób:

  dt<-data.frame (location = rep (letters [1: 2], każdy = 4), czas = rep (1: 4,2), var = rnorm (8)) lg<-function (x) c (NA, x [1: (length (x) -1)]) dt $ lg <- ave (dt $ var, dt $ lokalizacja, FUN = lg)  
Matthew
2014-09-01 20:29:15 UTC
view on stackexchange narkive permalink

Z dplyr

  dt% >% group_by (lokalizacja)% >% mutate (lvar = lag (var))  
Wayne
2015-02-25 22:39:58 UTC
view on stackexchange narkive permalink

Warto przyjrzeć się pakietowi vars . Wygląda na to, że autoregresja wektorowa (VAR) jest tym, co możesz próbować zrobić.

kitsune
2016-04-27 00:58:17 UTC
view on stackexchange narkive permalink

Z DataCombine:

  library (DataCombine) slide (df, Var = "observationB", TimeVar = "date", GroupVar = "location", NewVar = "lead.observationB", slideBy = 1, keepInvalid = FALSE, reminder = FALSE)  

Dane również muszą zostać posortowane. Zamiast tego użyj slideBy = -1 dla opóźnień.

Sebastian
2020-09-02 02:39:36 UTC
view on stackexchange narkive permalink

Tylko dla krótkiej aktualizacji: nowym najszybszym sposobem na zrobienie tego w R jest użycie funkcji flag / L w pakiecie zwijania. collapse obsługuje również sekwencje opóźnień / odprowadzeń na wektorach, macierzach i ramkach danych.

Biblioteka
  (zwiń)
dt <- data.frame (location = rep (litery [1: 2], each = 4), time = rep (1: 4, 2), var = rnorm (8))
# Najszybszy sposób na dołączenie data.frame ze zmienną z opóźnieniem
setsransform (dt, lvar = flag (var, 1, location, time))
dt
czas lokalizacji var lvar
1 a 1 -0,5808824 NA
2 a 2 -0,1606213 -0,5808824
3 a 3 0,6499493 -0,1606213
4 a 4 -0,2126608 0,6499493
5 b 1 -0,5082747 NA
6 b 2 -0,7450488 -0,5082747
7 b 3 -1,5895110 -0,7450488
8 b 4 0,2482062 -1,5895110

# Używanie klas plm - obsługiwane przez collapse
pdt <- plm :: pdata.frame (dt)
flaga (pdt $ var)
a-1 a-2 a-3 a-4 b-1 b-2 b-3 b-4
NA -0,5808824 -0,1606213 0,6499493 NA -0,5082747 -0,7450488 -1,5895110

# Bezpośrednie użycie operatora lag
L (dt, 1, var ~ lokalizacja, ~ czas)
czas lokalizacji L1.var
1 a 1 NA
2 a 2 -0,5808824
3 a 3 -0,1606213
4 a 4 0,6499493
5 b 1 nd
6 b 2 -0,5082747
7 b 3 -0,7450488
8 b 4 -1,5895110

# Benchmark
biblioteka (data.table); ddt <- data.table (dt)
f2 <- function () ddt [, lvar: = shift (var), by = location]
f3 <- function () setsransform (dt, lvar = flag (var, 1, location, time))
microbenchmark :: microbenchmark (data.table = f2 (), collapse = f3 (), times = 1000L)

Jednostka: mikrosekundy
       wyr min lq średnia mediana uq max neval cld
 data. tabela 518,539 568,519 788,7076 638,579 779,5935 23060,711 1000 b
   zapaść 44,179 60,913 100,3122 78,094 104.1990 2941,214 1000 a
 


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...