Jak utworzyć zmienną opóźnienia w każdej grupie?
Mam dane. Tabela:
set.seed(1)
data <- data.table(time = c(1:3, 1:4),
groups = c(rep(c("b", "a"), c(3, 4))),
value = rnorm(7))data
# groups time value
# 1: b 1 -0.6264538
# 2: b 2 0.1836433
# 3: b 3 -0.8356286
# 4: a 1 1.5952808
# 5: a 2 0.3295078
# 6: a 3 -0.8204684
# 7: a 4 0.4874291
Chcę obliczyć opóźnioną wersję kolumny „wartość”
wewnątrz
„grupy” na każdym poziomie.
Wynik powinien wyglądać tak
# groups time value lag.value
# 1 a 1 1.5952808 NA
# 2 a 2 0.3295078 1.5952808
# 3 a 3 -0.8204684 0.3295078
# 4 a 4 0.4874291 -0.8204684
# 5 b 1 -0.6264538 NA
# 6 b 2 0.1836433 -0.6264538
# 7 b 3 -0.8356286 0.1836433
Próbowałem bezpośrednio użyć
lag:
data$lag.value <- lag(data$value)..... co oczywiście nie zadziała.
Ja też tego próbowałem:
unlist(tapply(data$value, data$groups, lag))
a1 a2 a3 a4 b1 b2 b3
NA -0.1162932 0.4420753 2.1505440 NA 0.5894583 -0.2890288
I to jest prawie to, czego chcę. Jednak wygenerowany wektor jest uporządkowany inaczej niż uporządkowanie w data.table, co jest problematyczne.
Jaki jest najbardziej efektywny sposób zrobienia tego w base R, plyr, dplyr i data.table?
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
5 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
W przypadku wielu kolumn:
Aktualizacja
>
Z version & > = możemy użyć z jako lub . Wartość domyślna to .
Jeśli potrzebujesz czegoś odwrotnego, użyj
Korzystanie z oryginalnego zbioru danych
dane
>
Anonimowy użytkownik
Potwierdzenie od:
daje
Jak zauważył @BrianD, zakłada to niejawnie, że wartość jest już posortowana według grupy. Jeśli nie, posortuj je według grupy lub użyj argumentu w . Zwróć również uwagę, że z powodu
istniejący problem
https://coderoad.ru/28235074/
w przypadku niektórych wersji dplyr, ze względów bezpieczeństwa Argumenty i przestrzeń nazw muszą być jawnie określone.
Anonimowy użytkownik
Potwierdzenie od:
Pierwsza linia dodaje linię opóźnionych (+1) obserwacji. Drugi wiersz koryguje pierwszy wpis w każdej grupie, ponieważ opóźniona obserwacja należy do poprzedniej grupy.
Zwróć uwagę, że jest sformatowany jako , więc nie jest używany.
Anonimowy użytkownik
Potwierdzenie od:
Lub alternatywnie, podoba mi się pomysł umieszczenia go w funkcji z wybraną zmienną grupującą (AMI), kolumną rankingową (taką jak data lub inaczej) i wybraną liczbą opóźnień. Wymaga to również lazyeval i dplyr.
Anonimowy użytkownik
Potwierdzenie od:
gdy nie gwarantujesz, że każda grupa ma dane dla każdego okresu
... Oznacza to, że nadal masz regularnie rozmieszczone serie czasowe, ale może ich brakować tu i tam. Skoncentruję się na dwóch sposobach ulepszenia rozwiązania .
Zaczniemy od tych samych danych co Ty ...
... ale teraz usuniemy kilka wierszy
Proste rozwiązanie już nie działa
>
Możesz zobaczyć, że chociaż nie mamy wartości dla przypadku , powyższe nadal pokazuje wartość opóźnienia w , czyli w rzeczywistości wartość w punkcie .
Prawidłowe rozwiązanie >
Chodzi o to, że dodajemy brakujące (grupowe, tymczasowe) kombinacje. to
nieskuteczny
dla BARDZO pamięci, gdy masz wiele możliwych kombinacji (grup, czasów), ale wartości są rzadko przechwytywane.
Zauważ, że mamy teraz NA w , co powinno być oczekiwanym zachowaniem. To samo z .
Żmudne, ale poprawne rozwiązanie przy użyciu klasy >
To rozwiązanie powinno działać lepiej z punktu widzenia pamięci, gdy liczba przypadków jest bardzo duża, ponieważ zamiast wypełniać brakujące obserwacje NA, wykorzystuje indeksy.
Na koniec sprawdźmy, czy oba poprawne rozwiązania są rzeczywiście równe: