A Vectors fogalomnál láttuk, hogy egy vektor használható feltételes kifejezésben, logikai vektort eredményezve.
Ez pedig olyan függvényekben használható, mint az all() és az any().
v <- c(4, 7, 10)
v >= 6
#> [1] FALSE TRUE TRUE
all(v > 6)
#> [1] FALSE # not all elements match this condition
any(v > 6)
#> [1] TRUE # at least one element matches
A technika ennél sokkal többre képes.
Egy vektor kiválasztott elemeit indexszámmal vagy indexek vektorával lehet kiemelni:
v <- 5:10
v
#> [1] 5 6 7 8 9 10
v[3]
#> [1] 7
v[c(2, 4)]
#> [1] 6 8
Alternatívaként használj logikai vektort az eredeti vektor szűrésére; ez visszaadja azon elemek részhalmazát, amelyek TRUE értékre illeszkednek:
v <- 1:3
bools <- c(FALSE, TRUE, TRUE)
v[bools]
#> [1] 2 3
Innen már csak egy kis lépés a logikai vektor előállítása feltételes kifejezéssel:
bools <- v >= 2
bools
#> [1] FALSE TRUE TRUE
v[bools]
#> [1] 2 3
# simpler form
v[v >= 2]
#> [1] 2 3
Ezek a feltételes kifejezések tetszőlegesen összetettek lehetnek, több vektort vagy függvényt is bevonhatnak:
v <- 1:10
w <- 10:1
# pairwise comparison
v > w
#> [1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
# shorter form
v[v > w]
#> [1] 6 7 8 9 10
Ezt a fogalmat Vektorszűrésnek neveztük el, remélve, hogy a programozók legszélesebb körében is érthető lesz.
Az R közösségében a részhalmazképzés kifejezés valószínűleg gyakoribb.
Az egyszerűség kedvéért a fenti példák mind azonos hosszúságú vektorokat hasonlítottak össze. Mi történik, ha a hosszúságok nem egyeznek?
A válasz valami nagyon hatékony, ha szándékosan használod, de zavaró, ha nem számítasz rá.
Egy példa:
v <- 1:6
cond <- c(TRUE, FALSE)
v[cond]
#> [1] 1 3 5
Mi történt itt? Egy 6 hosszúságú vektort indexeltünk egy 2 hosszúságú logikai vektorral, de eredményül egy 3 hosszúságú vektort kaptunk.
Ha egy vektor valahogy „túl rövid” ahhoz a kifejezéshez, amelyben használják, az R addig ismétli, amíg el nem éri a kívánt hosszúságot. Ezt nevezik „újrahasznosításnak”.
Ez a c(TRUE, FALSE) vektorunkat c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE) vektorrá alakította, majd a v[cond] visszaadta a v TRUE értékeit: ebben az esetben a páratlan számokat.
Akkor mi történik a következő példában?
v <- 1:3
0.5 * v
#> [1] 0.5 1.0 1.5
2 + v
#> [1] 3 4 5
Elsőre skalárral való szorzásnak és (kissé furcsa) skalárral való összeadásnak tűnik, de az R-ben nincsenek skalárok.
Ehelyett a számok újrahasznosulnak, hogy egy v hosszúságával megegyező vektort kapjunk, majd az aritmetikai művelet elemenkénti alkalmazására kerül sor a c(0.5, 0.5, 0.5) vagy c(2, 2, 2) segítségével.
Az újrahasznosítás nagyon-nagyon hasznos, de győződj meg róla, hogy tényleg ezt szeretnéd.
A vektorok hosszának kisebb eltérése (pl. 99 és 100) zavaró hibákat okozhat.
Egyes szerzők azt javasolják, hogy az újrahasznosítást csak akkor használd, ha az egyik vektor hossza 1.
A which() függvény egy logikai argumentumot vár, és visszaadja azon indexek vektorát, amelyek TRUE értéket adnak.
v
#> [1] 2 7 9
v[v > 5] # returns values
#> [1] 7 9
which(v > 5) # returns indices
#> [1] 2 3
A korábbi szakaszok arról szóltak, hogyan találjunk valamilyen feltételnek megfelelő elemeket.
Ha csak azt szeretnéd tudni, hogy a vektor tartalmaz-e egy adott elemet, használd a %in% operátort.
3 %in% 1:5
#> [1] TRUE
7 %in% 1:5
#> [1] FALSE
Ez funkcionálisan egyenértékű a következő kóddal, de sokkal kényelmesebb:
length(v[v == 3]) > 0
#> [1] TRUE
Létezik egy %notin% operátor is, amely a %in% logikai not értékét adja.