Sök…


Anmärkningar

En körning är en i följd sekvens av upprepade värden eller observationer. För upprepade värden beskriver R: s "körlängdkodning" kort en vektor i termer av dess körningar. Överväga:

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

Vi har en längd på 1s; sedan en längd-tre körning av 2s; sedan en längd-en körning av 3s; och så vidare. R: s körlängdkodning fångar alla längder och värden på en vektors körningar.

Extensions

En körning kan också hänvisa till på varandra följande observationer i tabelldata. Medan R inte har ett naturligt sätt att koda dessa, kan de hanteras med rleid från data.table-paketet (för närvarande en blindvägslänk) .

Körningslängd med "rle"

Körning av körlängd fångar längden på körningar av på varandra följande element i en vektor. Tänk på en exempelvektor:

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

rle funktionen extraherar varje körning och dess längd:

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

Värdena för varje körning fångas i r$values :

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

Detta fångar att vi först såg en körning av 1: er, sedan en körning av 2: er, sedan en körning av 3: er, sedan en körning av 1: er, och så vidare.

Längderna för varje körning fångas i r$lengths :

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

Vi ser att den första körningen av 1: er var av längd 1, körningen av 2: er som följde var av längd 3, och så vidare.

Identifiera och gruppera efter körningar i bas R

Man kanske vill gruppera sina data efter en variabels körning och utföra någon slags analys. Tänk på följande enkla datasats:

(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

Variabeln x har tre körningar: en körning med längd 2 med värde 1, en körning av längd 3 med värde 2 och en körning av längd 1 med värde 1. Vi kanske vill beräkna medelvärdet för variabel y i var och en av körningar med variabel x (dessa medelvärden är 1,5, 4 och 6).

I bas R skulle vi först beräkna rle x variabeln med hjälp av rle :

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

Nästa steg är att beräkna körnumret för varje rad i vårt datasæt. Vi vet att det totala antalet körningar är length(r$lengths) , och längden på varje körning är r$lengths , så vi kan beräkna körantalet för vart och ett av våra körningar med rep :

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

Nu kan vi använda tapply att beräkna medelvärdet y värdet för varje körning genom att gruppera på flykt id:

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

Identifiera och gruppera efter körningar i data.table

Paketet data.table ger ett bekvämt sätt att gruppera efter körningar i data. Tänk på följande exempeldata:

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

Variabeln x har tre körningar: en körning av längd 2 med värde 1, en körning av längd 3 med värde 2 och en körning av längd 1 med värde 1. Vi kanske vill beräkna medelvärdet för variabel y i var och en av körningar med variabel x (dessa medelvärden är 1,5, 4 och 6).

Rleidfunktionen rleid tillhandahåller en id som indikerar kör-id för varje element i en vektor:

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

Man kan sedan enkelt gruppera på detta kör-ID och sammanfatta y data:

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

Körning i körlängd för att komprimera och dekomprimera vektorer

Långa vektorer med långa körningar med samma värde kan komprimeras betydligt genom att lagra dem i deras körlängdkodning (värdet på varje körning och antalet gånger som värdet upprepas). Tänk som exempel på en vektor med en längd på 10 miljoner med ett stort antal 1: er och endast ett litet antal 0: er:

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

Att lagra 10 miljoner poster kommer att kräva betydande utrymme, men vi kan istället skapa en dataram med körlängdskodningen för denna vektor:

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

Från körlängdkodningen ser vi att de första 52 818 värdena i vektorn är 1, följt av en enda 0, följt av 219 329 i följd 1, följt av en 0 och så vidare. Körlängdskodningen har bara 207 poster, vilket kräver att vi bara lagrar 414 värden istället för 10 miljoner värden. Eftersom rle.df är en dataram, kan den lagras med standardfunktioner som write.csv .

Dekomprimering av en vektor i körlängdkodning kan åstadkommas på två sätt. Den första metoden är att helt enkelt ringa rep genom att values värdelementet i körlängdkodningen som det första argumentet och lengths i körlängdkodningen som det andra argumentet:

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

Vi kan bekräfta att våra dekomprimerade data är identiska med våra ursprungliga data:

identical(decompressed, dat)
# [1] TRUE

Den andra metoden är att använda R: s inbyggda inverse.rle funktion på rle objektet, till exempel:

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

Vi kan bekräfta igen att detta producerar exakt den ursprungliga dat :

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow