R Language
Kodowanie długości przebiegu
Szukaj…
Uwagi
Przebieg jest kolejną sekwencją powtarzanych wartości lub obserwacji. W przypadku powtarzanych wartości „kodowanie długości przebiegu” R zwięźle opisuje wektor pod względem jego przebiegów. Rozważać:
dat <- c(1, 2, 2, 2, 3, 1, 4, 4, 1, 1)
Mamy ciąg 1s długości; następnie dwójka długości trzech sekund; następnie jeden odcinek długości 3s; i tak dalej. Kodowanie długości przebiegu R przechwytuje wszystkie długości i wartości przebiegów wektora.
Rozszerzenia
Przebieg może również odnosić się do kolejnych obserwacji w danych tabelarycznych. Chociaż R nie ma naturalnego sposobu ich kodowania, można je obsłużyć przy pomocy rleid
z pakietu data.table (obecnie link ślepy zaułek) .
Kodowanie w czasie wykonywania za pomocą `rle`
Kodowanie długości przebiegu przechwytuje długości przebiegów kolejnych elementów w wektorze. Rozważ przykładowy wektor:
dat <- c(1, 2, 2, 2, 3, 1, 4, 4, 1, 1)
Funkcja rle
wyodrębnia każdy przebieg i jego długość:
r <- rle(dat)
r
# Run Length Encoding
# lengths: int [1:6] 1 3 1 1 2 2
# values : num [1:6] 1 2 3 1 4 1
Wartości dla każdego przebiegu są rejestrowane w r$values
:
r$values
# [1] 1 2 3 1 4 1
To pokazuje, że najpierw widzieliśmy ciąg 1, potem bieg 2, potem bieg 3, potem bieg 1 i tak dalej.
Długości każdego przebiegu są rejestrowane w r$lengths
:
r$lengths
# [1] 1 3 1 1 2 2
Widzimy, że początkowy ciąg 1 był długości 1, bieg 2, który nastąpił, miał długość 3 i tak dalej.
Identyfikacja i grupowanie według przebiegów w bazie R
Można pogrupować dane według przebiegów zmiennej i przeprowadzić jakąś analizę. Rozważ następujący prosty zestaw danych:
(dat <- data.frame(x = c(1, 1, 2, 2, 2, 1), y = 1:6))
# x y
# 1 1 1
# 2 1 2
# 3 2 3
# 4 2 4
# 5 2 5
# 6 1 6
Zmienna x
ma trzy przebiegi: przebieg o długości 2 o wartości 1, przebieg o długości 3 o wartości 2 i przebieg o długości 1 o wartości 1. Możemy chcieć obliczyć średnią wartość zmiennej y
w każdym przebiegi zmiennej x
(te średnie wartości wynoszą 1,5, 4 i 6).
W bazie R najpierw obliczymy kodowanie długości zmiennej zmiennej x
za pomocą rle
:
(r <- rle(dat$x))
# Run Length Encoding
# lengths: int [1:3] 2 3 1
# values : num [1:3] 1 2 1
Następnym krokiem jest obliczenie numeru przebiegu każdego wiersza naszego zestawu danych. Wiemy, że całkowita liczba przebiegów to length(r$lengths)
, a długość każdego przebiegu to r$lengths
, więc możemy obliczyć liczbę przebiegów każdego z naszych rep
:
(run.id <- rep(seq_along(r$lengths), r$lengths))
# [1] 1 1 2 2 2 3
Teraz możemy użyć tapply
do obliczenia średniej wartości y
dla każdego uruchomienia, grupując według identyfikatora uruchomienia:
data.frame(x=r$values, meanY=tapply(dat$y, run.id, mean))
# x meanY
# 1 1 1.5
# 2 2 4.0
# 3 1 6.0
Identyfikacja i grupowanie według przebiegów w data.table
Pakiet data.table zapewnia wygodny sposób grupowania według przebiegów w danych. Rozważ następujące przykładowe dane:
library(data.table)
(DT <- data.table(x = c(1, 1, 2, 2, 2, 1), y = 1:6))
# x y
# 1: 1 1
# 2: 1 2
# 3: 2 3
# 4: 2 4
# 5: 2 5
# 6: 1 6
Zmienna x
ma trzy przebiegi: przebieg o długości 2 o wartości 1, przebieg o długości 3 o wartości 2 i przebieg o długości 1 o wartości 1. Możemy chcieć obliczyć średnią wartość zmiennej y
w każdym przebiegi zmiennej x (te średnie wartości wynoszą 1,5, 4 i 6).
Funkcja rleid rleid
zapewnia identyfikator wskazujący identyfikator uruchomienia każdego elementu wektora:
rleid(DT$x)
# [1] 1 1 2 2 2 3
Następnie można łatwo grupować według tego identyfikatora przebiegu i podsumowywać dane y
:
DT[,mean(y),by=.(x, rleid(x))]
# x rleid V1
# 1: 1 1 1.5
# 2: 2 2 4.0
# 3: 1 3 6.0
Kodowanie typu run do kompresji i dekompresji wektorów
Długie wektory o długich przebiegach o tej samej wartości można znacznie skompresować, przechowując je w ich kodowaniu długości przebiegu (wartość każdego przebiegu i liczba powtórzeń tej wartości). Jako przykład rozważmy wektor o długości 10 milionów z ogromną liczbą jedynek i tylko niewielką liczbą zer:
set.seed(144)
dat <- sample(rep(0:1, c(1, 1e5)), 1e7, replace=TRUE)
table(dat)
# 0 1
# 103 9999897
Przechowywanie 10 milionów pozycji będzie wymagało znacznej przestrzeni, ale zamiast tego możemy stworzyć ramkę danych z kodowaniem długości tego wektora:
rle.df <- with(rle(dat), data.frame(values, lengths))
dim(rle.df)
# [1] 207 2
head(rle.df)
# values lengths
# 1 1 52818
# 2 0 1
# 3 1 219329
# 4 0 1
# 5 1 318306
# 6 0 1
Z kodowania długości przebiegu widzimy, że pierwsze 52 818 wartości w wektorze to 1, a następnie pojedyncze 0, następnie 219 329 kolejnych 1, następnie 0 i tak dalej. Kodowanie długości przebiegu ma tylko 207 pozycji, co wymaga od nas przechowywania tylko 414 wartości zamiast 10 milionów wartości. Ponieważ rle.df
jest ramką danych, można ją przechowywać przy użyciu standardowych funkcji, takich jak write.csv
.
Dekompresję wektora w kodowaniu przebiegowym można wykonać na dwa sposoby. Pierwszym sposobem jest po prostu wywołać rep
, przekazując values
elementu kodowania długości jak pierwszy argument i lengths
elementu kodowania długości jako drugi argument:
decompressed <- rep(rle.df$values, rle.df$lengths)
Możemy potwierdzić, że nasze zdekompresowane dane są identyczne z naszymi oryginalnymi danymi:
identical(decompressed, dat)
# [1] TRUE
Drugą metodą jest użycie wbudowanej funkcji R inverse.rle
na obiekcie rle
, na przykład:
rle.obj <- rle(dat) # create a rle object here
class(rle.obj)
# [1] "rle"
dat.inv <- inverse.rle(rle.obj) # apply the inverse.rle on the rle object
Możemy potwierdzić, że to znowu produkuje dokładnie oryginalną dat
:
identical(dat.inv, dat)
# [1] TRUE