Ricerca…


Osservazioni

Una corsa è una sequenza consecutiva di valori o osservazioni ripetuti. Per i valori ripetuti, la "codifica run-length" di R descrive concisamente un vettore in termini di sue esecuzioni. Tenere conto:

dat <- c(1, 2, 2, 2, 3, 1, 4, 4, 1, 1)

Abbiamo una durata di una corsa di 1 s; quindi una durata di tre secondi di 2 secondi; quindi una durata di una corsa di 3 secondi; e così via. La codifica run-length di R cattura tutte le lunghezze e i valori delle corse di un vettore.

estensioni

Una corsa può anche riferirsi a osservazioni consecutive in un dato tabellare. Mentre R non ha un modo naturale di codificarli, possono essere gestiti con rleid dal pacchetto data.table (attualmente un link dead-end) .

Codifica run-length con `rle`

La codifica run-length cattura le lunghezze delle esecuzioni di elementi consecutivi in ​​un vettore. Considera un vettore di esempio:

dat <- c(1, 2, 2, 2, 3, 1, 4, 4, 1, 1)

La funzione rle estrae ogni corsa e la sua lunghezza:

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

I valori per ogni corsa sono catturati in r$values :

r$values
# [1] 1 2 3 1 4 1

Ciò dimostra che abbiamo visto per la prima volta una serie di 1, una di 2, una di 3, una di 1 e così via.

Le lunghezze di ogni corsa sono catturate in r$lengths :

r$lengths
# [1] 1 3 1 1 2 2

Vediamo che la serie iniziale di 1 era di lunghezza 1, la serie di secondi che seguì era di lunghezza 3, e così via.

Identificazione e raggruppamento per esecuzioni in base R

Si potrebbe desiderare di raggruppare i propri dati con le analisi di una variabile ed eseguire una sorta di analisi. Si consideri il seguente set di dati semplice:

(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

La variabile x ha tre esecuzioni: una corsa di lunghezza 2 con valore 1, una corsa di lunghezza 3 con valore 2 e una corsa di lunghezza 1 con valore 1. Potremmo voler calcolare il valore medio della variabile y in ognuna delle corse di variabile x (questi valori medi sono 1.5, 4 e 6).

Nella base R, dovremmo prima calcolare la codifica run-length della variabile x usando rle :

(r <- rle(dat$x))
# Run Length Encoding
#   lengths: int [1:3] 2 3 1
#   values : num [1:3] 1 2 1

Il prossimo passo è calcolare il numero di esecuzione di ogni riga del nostro set di dati. Sappiamo che il numero totale di esecuzioni è di length(r$lengths) e la lunghezza di ogni corsa è di r$lengths , quindi possiamo calcolare il numero di esecuzioni di ciascuna delle nostre esecuzioni con rep :

(run.id <- rep(seq_along(r$lengths), r$lengths))
# [1] 1 1 2 2 2 3

Ora possiamo usare tapply per calcolare il valore y medio per ogni corsa raggruppando sull'id di esecuzione:

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

Identificazione e raggruppamento per esecuzioni in data.table

Il pacchetto data.table offre un modo conveniente per raggruppare mediante le esecuzioni nei dati. Considera i seguenti dati di esempio:

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

La variabile x ha tre esecuzioni: una corsa di lunghezza 2 con valore 1, una corsa di lunghezza 3 con valore 2 e una corsa di lunghezza 1 con valore 1. Potremmo voler calcolare il valore medio della variabile y in ognuna delle corse di variabile x (questi valori medi sono 1.5, 4 e 6).

La funzione rleid rleid fornisce un id che indica l'id di esecuzione di ciascun elemento di un vettore:

rleid(DT$x)
# [1] 1 1 2 2 2 3

Si può quindi facilmente raggruppare su questo ID di esecuzione e riepilogare i dati 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

Codifica run-length per comprimere e decomprimere i vettori

I vettori lunghi con long run dello stesso valore possono essere compressi in modo significativo memorizzandoli nella loro codifica run-length (il valore di ogni esecuzione e il numero di volte in cui il valore viene ripetuto). Ad esempio, considera un vettore di lunghezza 10 milioni con un numero enorme di 1 e solo un piccolo numero di 0:

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

Memorizzare 10 milioni di voci richiederà uno spazio significativo, ma possiamo invece creare un frame di dati con la codifica run-length di questo vettore:

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

Dalla codifica run-length, vediamo che i primi 52.818 valori nel vettore sono 1, seguiti da un singolo 0, seguiti da 219.329 1 consecutivi, seguiti da uno 0 e così via. La codifica run-length ha solo 207 voci, richiedendoci di memorizzare solo 414 valori invece di 10 milioni di valori. Poiché rle.df è un frame di dati, può essere memorizzato utilizzando funzioni standard come write.csv .

La decompressione di un vettore nella codifica run-length può essere eseguita in due modi. Il primo metodo consiste nel chiamare semplicemente rep , passando l'elemento values della codifica run-length come primo argomento e l'elemento lengths della codifica run-length come secondo argomento:

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

Possiamo confermare che i nostri dati decompressi sono identici ai nostri dati originali:

identical(decompressed, dat)
# [1] TRUE

Il secondo metodo consiste nell'utilizzare la funzione inverse.rle integrata di rle sull'oggetto rle , ad esempio:

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

Possiamo confermare ancora che questo produce esattamente il dat originale:

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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow