R Language
Körning av körlängd
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