A Bevezetés az R programozási nyelvbe sorozat írásai egymásra épülnek. Aki most ismerkedik az R-rel, annak erősen ajánlom, hogy a korábbi blogposztokkal kezdje. A sorozat eddig elkészült tagjai:
- Vektorok
- Adatkeretek
- Listák
Az alábbiakban R nyelven (v4.1.2) írt kódot használok a feladat végrehajtásához. A magyarázó szövegek közé ékelt fekete kódblokkok tartalmát az RStudio-ban egymás alá illesztve elvileg bárki által reprodukálható az itt bemutatott műveletsor. A kódblokkok # kezdetű sorai pusztán magyarázó funkcióval bírnak, ezekre a program futtatásakor nincs szükség.
A lista létrehozása
A listák tehát bizonyos adatok vagy adatstruktúrák összefogására, együttes kezelésére valók. Szemben a vektorokkal, amelyekben azonos – csak numerikus, karakteres, vagy logikai – típusú egyedi adatokat tárolhatunk, a listák heterogének: a különböző típusokba tartozó egyedi adatok mellett adatstruktúrákat is tartalmazhatnak. Ezek adott esetben tetszőleges mélységben egymásba ágyazhatók.
Egy n elemből áll üres listát a vector(mode = "list", length = n)
utasítással tudunk létrehozni. Sokszor azonban már alapból fel szeretnénk tölteni adatokkal a listánkat. Ekkor a list()
függvényt használjuk, amelynek paraméterei a létrehozandó lista elemei lesznek.
Az alábbiakban egy olyan listát fogok előállítani, amelynek elemei a következők: egy karakterlánc, egy numerikus vektor, egy logikai érték, egy numerikus érték, egy adatkeret, valamint egy lista. Ezeket most közvetlenül a list()
függvényben definiáltam, de természetesen annak sem lenne akadálya, ha paraméterként külső változókat adnánk meg.
|
|
## [[1]]
## [1] "ez egy rövid szöveg"
##
## [[2]]
## [1] 100 200 300 400 500
##
## [[3]]
## [1] TRUE
##
## [[4]]
## [1] 4
##
## [[5]]
## oszlop1 oszlop2
## 1 1 6
## 2 2 7
## 3 3 8
## 4 4 9
## 5 5 10
##
## [[6]]
## [[6]][[1]]
## [1] TRUE
##
## [[6]][[2]]
## [1] FALSE
##
## [[6]][[3]]
## [1] FALSE
##
## [[6]][[4]]
## [1] TRUE TRUE FALSE
Hozzáférés a lista elemeihez
A listák tartalmára sokszor nem egyben, hanem elemenként van szükségünk. Ezek kiválasztásához tudni kell, hogy lista elemei fentről lefelé (balról jobbra) haladva, 1-től kezdve kapják meg a sorszámukat, vagyis az indexüket. (Vannak egyébként olyan programozási nyelvek is, amelyek 0-tól indexelnek.)
A lista elemeinek számát a length()
függvénnyel kaphatjuk meg. A kiválasztandó elemek indexét a lista nevéhez illesztett dupla szögletes zárójelben kell megadni.
|
|
## [1] 6
|
|
## [1] "ez egy rövid szöveg"
Ahogy korábban említettem, egy lista nemcsak egyedi értékeket, hanem adatstruktúrákat is tartalmazhat. Ez utóbbiak tovább indexelhetők a kérdéses adatstruktúra saját szabályai szerint. Ezeket a lehetőségeket korábban már igen részletesen bemutattam a vektorokról és az adatkeretekről szóló posztokban, míg a listák esetében ez e posztban leírtak az irányadók. Nézzünk most néhány példát ezekre!
|
|
## [1] 400 500
|
|
## [1] 1 2 3 4 5
|
|
## [1] 8 10
|
|
## [1] TRUE
Ha tehát valamilyen adatstruktúrát tartalmaz a listánk, akkor az adott elem kiválasztása után úgy kell folytatnunk az utasítást, mint ha egy önálló vektort, adatkeretet vagy éppen listát akarnánk indexelni.
A lista elemeinek elnevezése
Amennyiben nagyon sok eleme van a listánknak, akkor jobban járunk, ha ezeknek valamilyen nevet adunk, mert úgy könnyebb emlékezni rájuk.
A különböző objektumok – tehát nem csak a listák – elnevezésekor érdemes valamilyen egységes elvet követni. Én például általában az ún. camelCase kódolási konvenciót követem, amelyben az eredetileg több szóból álló elnevezések egyes elemei szóközök nélkül kerülnek egymás mellé, a második elemtől fogva mindig nagybetűvel kezdve. Egyébként pedig csupa kisbetűvel és ékezetek nélkül írom őket.Bár az R programozási nyelv megengedné, hogy szóközöket használjunk az elnevezésekben, de ez bizonyos esetekben bonyodalmakhoz vezethet. Inkább kerüljük ezt a megoldást.
A camelCase kódolási konvenció (a kép forrása)
Az alábbi kódblokkban közvetlenül a lista létrehozásakor adom meg az egyes elemek nevét. Ezzel az új listával felülírom a régit.
|
|
## $egyediKarakterlanc
## [1] "ez egy rövid szöveg"
##
## $vektor
## [1] 100 200 300 400 500
##
## $egyediLogikai
## [1] TRUE
##
## $egyediNumerikus
## [1] 4
##
## $adatkeret
## oszlop1 oszlop2
## 1 1 6
## 2 2 7
## 3 3 8
## 4 4 9
## 5 5 10
##
## $lista
## $lista[[1]]
## [1] TRUE
##
## $lista[[2]]
## [1] FALSE
##
## $lista[[3]]
## [1] FALSE
##
## $lista[[4]]
## [1] TRUE TRUE FALSE
A lista elemeinek nevét a names()
függvénnyel tudjuk lekérdezni. Ekkor egy karakteres vektort kapunk vissza.
|
|
## [1] "egyediKarakterlanc" "vektor" "egyediLogikai"
## [4] "egyediNumerikus" "adatkeret" "lista"
A neveket az unname()
függvénnyel lehet eltávolítani a listából. Ha ezt az utasítást rámentjük az eredeti listánkra, akkor eltűnnek abból a nevek.
|
|
## NULL
Arra is lehetőségünk van azonban, hogy utólag nevezzük el a lista egy-egy, vagy éppen az összes elemét. Ehhez ugyancsak a names()
függvényt használjuk, amelynek paramétere maga a lista lesz. Ehhez rendeljük a hozzá karakteres formában a nevet vagy neveket.
-
Ha csak egy adott elemnek akarunk nevet adni, akkor annak indexét hozzá kell illeszteni az említett függvényhez.
-
Ha a lista minden elemének nevet akarunk adni, akkor értelemszerűen egy olyan karaktervektort kell megadnunk, amelynek hossza megegyezik a lista elemeinek számával. Egyébként csak a karaktervektor hosszának megfelelő számú elem kap nevet a listánk elején.
Amennyiben a lista adott eleme már el van nevezve, akkor az a művelet nyomán felülíródik.
|
|
## [1] "egyediKarakterlanc" NA NA
## [4] NA NA NA
|
|
## [1] "egyediKarakterlanc" "vektor" "egyediLogikai"
## [4] "egyediNumerikus" "adatkeret" "lista"
A lista elemeinek azért érdemes nevet adni, mert ettől kezdve az elnevezésekkel is hivatkozhatunk azokra. Ekkor a listaNeve$elemNeve
formában tudunk hozzáférni a lista elemeihez. De természetesen a numerikus indexelés lehetősége is megmarad, sőt akár vegyesen is használhatjuk őket.
Lássuk ismét a korábban már megismert példákat, ezúttal az elnevezéseknek megfelelően átalakítva!
|
|
## [1] 400 500
|
|
## [1] 1 2 3 4 5
|
|
## [1] 8 10
|
|
## [1] TRUE
Ugyanakkor az elnevezések segítségével úgy is hivatkozni tudunk a lista elemeire, ha a dupla szögletes zárójelben karakterláncként adjuk meg azokat. Alább erre látunk egy példát.
|
|
## [1] 100 200 300 400 500
A listák manipulálása
Az elemek felülírása
A listák egyes elemeit úgy tudjuk lecserélni, hogy az adott indexű vagy nevű elemet felülírjuk valami mással.
|
|
## [1] "ez egy kicsit hosszabb szöveg"
|
|
## [1] 1 2 3 4 5
Az elemek törlése
Ha a NULL
értékkel írunk felül egy elemet, akkor azzal törölni tudjuk a listából. Ebben az esetben az eltávolított elem indexét rögtön megkapja a sorban következő elem. Vagyis a lista indexei átszámozódnak. Erre figyelni kell, ha számokkal indexelünk!
|
|
## [1] 1 2 3 4 5
|
|
## [1] 5
Új elemek hozzáadása
Egy listához az append()
függvénnyel tudunk új elemet hozzáadni. Ez alapértelmezés szerint lista végére kerül. Az after
paraméter használatával viszont meghatározhatjuk azt az indexet, ami után be akarjuk szúrni az új elemet.
Most például visszahelyezem a lista elejére a törölt elemet, majd elnevezem azt az eredeti verziónak megfelelően.
|
|
## [1] "ez egy kicsit hosszabb szöveg"
|
|
## [1] 6
Az imént egy egyedi értéket adtunk hozzá a listánkhoz. Ha viszont egy adatstruktúrát akarunk ezen a módon hozzáadni, akkor azt sajnos elemekre szedi és úgy csatolja a listához az append()
függvény.
Próbáljunk meg például egy három elemből álló karaktervektort hozzáadni a listánk végéhez!
|
|
## $egyediKarakterlanc
## [1] "ez egy kicsit hosszabb szöveg"
##
## $vektor
## [1] 1 2 3 4 5
##
## $egyediLogikai
## [1] TRUE
##
## $egyediNumerikus
## [1] 4
##
## $adatkeret
## oszlop1 oszlop2
## 1 1 6
## 2 2 7
## 3 3 8
## 4 4 9
## 5 5 10
##
## $lista
## $lista[[1]]
## [1] TRUE
##
## $lista[[2]]
## [1] FALSE
##
## $lista[[3]]
## [1] FALSE
##
## $lista[[4]]
## [1] TRUE TRUE FALSE
##
##
## [[7]]
## [1] "A"
##
## [[8]]
## [1] "B"
##
## [[9]]
## [1] "C"
Mit látunk itt? A megadott vektor elemei egyenként, önálló elemként adódtak hozzá a listához. És ehhez hasonló dolgot tapasztalnánk akkor is, ha egy adatkeret vagy egy másik lista hozzáadásával próbálkoznánk.
Ha tehát valamilyen adatstruktúrával szeretnénk kibővíteni a listánkat, akkor azt nem az append()
függvénnyel tudjuk hozzáadni. Ebben az esetben úgy kell eljárni, hogy direktben a lista valamelyik eleméhez rendeljük hozza a kérdéses vektort, adatkeretet vagy listát.
Amennyiben a lista végéhez akarjuk hozzáadni új elemként az adatstruktúrát, akkor indexként a length(listaNeve)+1
értéket adjuk meg. Ezzel tudunk a lista aktuális hossza utáni első indexre pozícionálni. Ha jól dolgoztunk, akkor jelen esetben a 10. elemként kell megjelennie a hozzáadott vektornak.
|
|
## [1] "A" "B" "C"
Információk a listáról
A lista felépítéséről az str()
függvénnyel kérhetünk rövid áttekintést. Ennek segítségével információkat kapunk a listánk egyes elemeiről: azok nevéről (ha van), típusáról és az első néhány adatról.
|
|
## List of 10
## $ egyediKarakterlanc: chr "ez egy kicsit hosszabb szöveg"
## $ vektor : int [1:5] 1 2 3 4 5
## $ egyediLogikai : logi TRUE
## $ egyediNumerikus : num 4
## $ adatkeret :'data.frame': 5 obs. of 2 variables:
## ..$ oszlop1: int [1:5] 1 2 3 4 5
## ..$ oszlop2: int [1:5] 6 7 8 9 10
## $ lista :List of 4
## ..$ : logi TRUE
## ..$ : logi FALSE
## ..$ : logi FALSE
## ..$ : logi [1:3] TRUE TRUE FALSE
## $ : chr "A"
## $ : chr "B"
## $ : chr "C"
## $ : chr [1:3] "A" "B" "C"
A fentiekben egy bevezető jellegű áttekintést próbáltam adni az R programozási nyelvben használatos listákról. Ezek kezelése és manipulálása azonban nem merül ki a fentiekben. Jelen pillanatban viszont nem akarom túlbonyolítani a dolgot. Az esetspecifikus további lehetőségekre a későbbiekben még visszatérek majd.