Programozó programot programozni

Arra gondoltam, jó volna, ha a sok, hasonló paraméterrel rendelkező függvényemet egyszerre elindíthatnám ugyanazon az adatsoron, például így:

Először is érdemes udni, hogyan hívok meg egy függvényt, amit egy változóban kapok meg, egy olyan argumentummal, amit egy másikban. Példaként vegyűk az R beépített iris adatbázisát:

A do.call függvény egy karakterként kéri a függvény nevét, és egy elnevezett listában kéri az argumentumokat. Ezek alapján, ha egyszerre több függvényt szeretnénk meghívni, használhatjuk a megszokott *apply függvénycsaládot:

Megoldható az is, hogyha az iris adatok mindegyikén (legalábbis a számokon) szeretném elvégezni a feladatot, ugyanakkor az sapply erre már nem jó:

A probléma, hogy ebben az esetben az “isir$Sepal.Length” sztringre próbálja elvégezni az átlagszámítást, ami természetesen nem megy. (Egyébként próbálkoztam névvé alakítani, abban az esetben nem találja meg, és még nem tudom hogy miért). Érdemes tehát kicsit belevetni magunkat abba, hogyan íratunk meg az R-rel olyan kódokat, amiket később végre tud hajtani.

Ehhez azt kell tudnom, hogy fog kinézni a kifejezés (expression):

A [függvények] helyére a függvények neveit tartalmazó karakter vektor neve (esetemben f2), a [változó] helyére pedig az egyes oszlopok nevei kell kerüljenek. Először érdemes összerakni ezt a kifejezést:

Ebben a kódban már csak a változó nevét kell cserélgetni, amire viszont teljesen jó az sapply:

A ch1 a kód végrehajtása után egy karakter vektor lesz, minden egyes elemének van neve, és tartalma a kód, ami egy érvényes kifejezés (lesz, most még csak egy betűhalom), és az R végre fogja tudni hajtani mindet, ha tudja, hogy értelmeznie kell őket. Az értelmezést a parse függvény, a végrehajtást pedig az eval függvény végzi. Előbbinél figyelni kell, hogy egy sztring megadása a text paraméterbe kell kerüljön, különben egy fájl tartalmát fogja keresni. Tehát a

parancs során az R megajándékoz két, névvel ellátott számmal, azt sem kell kitalálni, melyiket melyik függvény eredményeként kaptam (ez a képesség engem nagyon kellemes meglepetésként ért). Tehát nem maradt más hátra, mint előre, és az eval(parse()) kombinációt a ch1 minden tajára elvégezni:

Teljes siker: kaptunk egy függvény és egy változólistát (f2 és v2), és azt megcsináltuk azok konkrét mivoltának ismerete nélkül. Ráadásként pedig egy szépen strukturált eredményt kaptunk: egy mátrixot, annak oszlopaiban a változónevekkel, soraiban pedig a függényekkel. Ez az sapply egyik argumentumának és alapbeállításának köszönhető (simplify=TRUE), ami, ha azonos típusúak az egyes függvények eredményei, összecsomagolja őket egy vektorba/mátrixba/tömbbe, ha pedig egyikbe sem tudja, akkor listaként adja vissza az eredményt. Ennek természetesen vannak veszélyei, de ilyen egyszerű feladatnál ezt még biztos tudja kezelni az R (érdemes kipróbálni, mi történik, ha a szórás kiszámítása helyett karakterré alakítjuk a számokat – ez nem csak típusban, hanem hosszban is eltérő eredményeket fog ugyanis adni. Egyúttal itt a kérdés is, amire még nem tudom a magyarázatot: hogyan sikerül az eredményt mátrixszá összegyúrnia az sapply-nak?)

Az iris adatok tartalmazzák az egyes példányok fajtáját is, a következő(nek szánt) bejegyzésben azt részletezem majd, hogyan lehet minden fajtára elvégezni a kívánt műveleteket (lehetőleg gyorsan), illetve hogyan lehet bonyolultabb függvényeket, amik több argumentummal is rendelkeznek, ellátni a szükséges információkkal.

Via: Programozó programot programozni