Поиск…


замечания

Прогон представляет собой последовательную последовательность повторяющихся значений или наблюдений. Для повторных значений 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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow