執行長度編碼以壓縮和解壓縮向量

通過將它們儲存在執行長度編碼中(每次執行的值和重複值的次數),可以顯著壓縮具有相同值的長執行的長向量。舉個例子,考慮一個長度為 1000 萬的向量,其中包含大量的 1 和 0,只有少量的 0:

set.seed(144)
dat <- sample(rep(0:1, c(1, 1e5)), 1e7, replace=TRUE)
table(dat)
#       0       1 
#     103 9999897 

儲存 1000 萬個條目將需要大量空間,但我們可以使用此向量的行程編碼來建立資料框:

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

從行程編碼中,我們看到向量中的前 52,818 個值是 1,接著是單個 0,接著是 219,329 個連續的 1,然後是 0,依此類推。遊程編碼只有 207 個條目,要求我們只儲存 414 個值而不是 1000 萬個值。由於 rle.df 是一個資料框,因此可以使用 write.csv 等標準函式進行儲存。

在遊程編碼中解壓縮向量可以通過兩種方式完成。第一種方法是簡單地呼叫 rep,將遊程編碼的 values 元素作為第一個引數傳遞,將遊程編碼的 lengths 元素作為第二個引數傳遞:

decompressed <- rep(rle.df$values, rle.df$lengths)

我們可以確認我們的解壓縮資料與原始資料相同:

identical(decompressed, dat)
# [1] TRUE

第二種方法是在 rle 物件上使用 R 的內建 inverse.rle 函式,例如:

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

我們可以再次確認這產生了原始的 dat

identical(dat.inv, dat)
# [1] TRUE