R Language
Кодировка длины
Поиск…
замечания
Прогон представляет собой последовательную последовательность повторяющихся значений или наблюдений. Для повторных значений R-кодировка «длина строки» кратко описывает вектор в терминах его прогонов. Рассматривать:
dat <- c(1, 2, 2, 2, 3, 1, 4, 4, 1, 1)
У нас есть пробег длиной 1 с; затем три пробега длиной 2 с; затем пробег длиной 3 с; и так далее. R-образная кодировка фиксирует все длины и значения пробегов вектора.
расширения
Прогон также может ссылаться на последовательные наблюдения в табличных данных. Хотя R не имеет естественного способа их кодирования, их можно обрабатывать с помощью rleid
из пакета data.table (в настоящее время это тупиковая ссылка) .
Кодировка длины пробега с `rle`
Кодировка длины выполнения фиксирует длины прогонов последовательных элементов в векторе. Рассмотрим пример вектора:
dat <- c(1, 2, 2, 2, 3, 1, 4, 4, 1, 1)
Функция rle
извлекает каждый пробег и его длину:
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
Значения для каждого прогона записываются в r$values
:
r$values
# [1] 1 2 3 1 4 1
Это фиксирует, что мы сначала увидели пробег в 1, затем пробег 2, затем пробег в 3, затем пробег в 1 и т. Д.
Длины каждого прогона захватываются по r$lengths
:
r$lengths
# [1] 1 3 1 1 2 2
Мы видим, что начальный пробег 1 был длиной 1, пробег 2, следующий за ним, был длиной 3 и т. Д.
Идентификация и группировка пробегами в базе R
Можно захотеть сгруппировать свои данные с помощью пробегов переменной и выполнить какой-то анализ. Рассмотрим следующий простой набор данных:
(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
Переменная x
имеет три пробега: пробег длиной 2 со значением 1, пробег 3 со значением 2 и пробег длиной 1 со значением 1. Мы могли бы захотеть вычислить среднее значение переменной y
в каждом из пробеги переменной x
(эти средние значения равны 1,5, 4 и 6).
В базовом R, мы сначала вычислить по длине прогона кодирование x
переменной с помощью rle
:
(r <- rle(dat$x))
# Run Length Encoding
# lengths: int [1:3] 2 3 1
# values : num [1:3] 1 2 1
Следующим шагом будет вычисление номера прогона каждой строки нашего набора данных. Мы знаем, что общее количество прогонов - length(r$lengths)
, а длина каждого пробега равна r$lengths
, поэтому мы можем вычислить номер пробега каждого из наших прогонов с rep
:
(run.id <- rep(seq_along(r$lengths), r$lengths))
# [1] 1 1 2 2 2 3
Теперь мы можем использовать tapply
для вычисления среднего значения y
для каждого прогона путем группировки на идентификаторе запуска:
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
Идентификация и группировка с помощью прогонов в data.table
Пакет data.table обеспечивает удобный способ группировки по прогонам в данных. Рассмотрим следующие примеры данных:
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
Переменная x
имеет три пробега: пробег длиной 2 со значением 1, пробег 3 со значением 2 и пробег длиной 1 со значением 1. Мы могли бы захотеть вычислить среднее значение переменной y
в каждом из пробеги переменной x (эти средние значения равны 1,5, 4 и 6).
Функция data.table rleid
предоставляет идентификатор, указывающий идентификатор запуска каждого элемента вектора:
rleid(DT$x)
# [1] 1 1 2 2 2 3
Затем можно легко группировать этот идентификатор запуска и суммировать данные 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
Кодировка длины для сжатия и распаковки векторов
Длинные векторы с длинными тиражами одного и того же значения могут быть значительно сжаты, сохраняя их в кодировке их длины (значение каждого прогона и количество повторений этого значения). В качестве примера рассмотрим вектор длиной 10 миллионов с огромным числом 1 и только небольшое число 0:
set.seed(144)
dat <- sample(rep(0:1, c(1, 1e5)), 1e7, replace=TRUE)
table(dat)
# 0 1
# 103 9999897
Для хранения 10 миллионов записей потребуется значительное пространство, но вместо этого мы можем создать кадр данных с кодировкой этого вектора длины:
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 значений вместо 10 миллионов значений. Поскольку rle.df
- это кадр данных, его можно сохранить с помощью стандартных функций, таких как write.csv
.
Декомпрессия вектора в кодировании длины строки может быть выполнена двумя способами. Первый метод просто вызвать rep
, передавая values
элемента кодирования длин серий в качестве первого аргумента и lengths
элемента кодирования длин серий в качестве второго аргумента:
decompressed <- rep(rle.df$values, rle.df$lengths)
Мы можем подтвердить, что наши распакованные данные идентичны нашим исходным данным:
identical(decompressed, dat)
# [1] TRUE
Второй способ заключается в использовании R встроенного в inverse.rle
функции на 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