Kurzusok
/
R
R
/
Feladatok
/
Logszintek
Logszintek

Logszintek

Tanulófeladat

Bevezetés

Háttér

A string idézőjelek közé zárt szövegrész. Az R minden jelenleg támogatott verziója UTF-8-ban kódolja a stringeket, így a világ nyelveinek többsége támogatható.

mystring <- "some text"
mystring
#> [1] "some text"
typeof(mystring)
#> [1] "character"

Sajnos a terminológia zavaró lehet azoknak a programozóknak, akik más nyelveket ismernek.

Bár a type értéke character, az R nem tesz különbséget egyetlen betű (amit több más nyelvben char-nak hívnak, de R-ben nem) és egy hosszú string között. Mindkettő egyetlen elem, és felváltva állhat aposztrófok ' ' vagy idézőjelek " " között.

A stílusútmutató a kettős idézőjelek használatát javasolja, kivéve, ha kettős idézőjelet szeretnél a stringen belül elhelyezni anélkül, hogy escape-elned kellene őket.

str2 <- 'String with "quotes"'  # convenience format
str2
#> [1] "String with \"quotes\""    # standard format

A character vector tehát stringek vektora, ahol minden string egyetlen elem.

s <- c("some", "strings")
s
#> [1] "some"    "strings"
length(s)
#> [1] 2
length(s[1])  # the number of vector elements, not the string length
#> [1] 1

nchar(s[1])  # the number of characters in the string "some"
#> [1] 4

A fenti példában a length(s[1]) ugyanaz, mint a length("some"): a vektorelemek számát adja meg, nem a string hosszát.

Egy-egy string módosítása természetesen lehetséges, ahogy a fenti példában a nchar() is mutatja, de ehhez speciális függvények kellenek, amelyeket alább tárgyalunk.

Stringfüggvények

A base R-ben szinte minden lehetséges, de sok programozó szerint a stringkezelés támogatása meglehetősen korlátozott és zavaró.

Szerencsére vannak tidyverse csomagok, amelyek sokkal intuitívabbak, rugalmasabbak és önmagukban konzisztensebbek.

Base R

Még mindig sok régi kód használ régi stílusú stringfüggvényeket. Ide tartozik az Exercism közösségi megoldásainak nagy része is.

Ráadásul kis feladatoknál hasznos lehet a beépített függvények használata egy nagy csomag importálása helyett. Az R-kurzus karbantartói jellemzően ezt a megközelítést választják, amikor mintamegoldásokat írnak a feladatok ellenőrzéséhez.

Ezért érdemes megismerkedni a régi megközelítésekkel is.

nchar

Egy string karaktereinek számát adja vissza.

nchar("string")
#> [1] 6

nchar("Hrōðgār") # a person in Beowulf, written in Old English
#> [1] 7

Az, hogy mit is jelent pontosan a »karakter«, (bonyolult!) téma, és meghaladja ennek az anyagnak a kereteit. Csak jegyezz meg néhány dolgot a fenti példákból:

  • Bár belül C-ben vannak megvalósítva, az R stringjei nem \0-termináltak (ami 1-gyel növelné a hosszukat).
  • A több bájtos Unicode-karaktereket úgy kezeli, ahogy várnád/remélnéd. A »Hrōðgār« 7 karakterből áll (más néven »rúna« vagy »kódpont«), de a tároláshoz 10 bájtra van szükség.
paste és paste0

Tetszőleges számú stringet fűz össze egyetlen stringgé.

A paste esetében opcionálisan megadható egy elválasztó: az alapértéke egy szóköz.

A paste0(v) ugyanaz, mint a paste(v, sep = "").

paste("bits", "of", "a", "string")
#> [1] "bits of a string"
paste0("bits", "of", "a", "string")
#> [1] "bitsofastring"
sprintf

A stringek összeállításának finomabb szabályozásához az R a C-ből vette át a sprintf függvényt (és több későbbi nyelv is: a Wikipédia mintegy 30-at sorol fel).

r <- 5.3
pi <- 3.14159
sprintf("A circle of radius %.1f has area %.2f", r, pi * r^2)
#> [1] "A circle of radius 5.3 has area 88.25"
trimws

A kezdő és/vagy záró whitespace eltávolítható a trimws() függvénnyel:

s <- "    messy string   "
trimws(s)
#> [1] "messy string"

Van egy which = "left" (vagy „right”) paraméter, amellyel elkerülhető mindkét vég levágása.

substr

Egyetlen stringen működik, és visszaadja a két határ közötti részstringet (a határokat is beleértve).

substr("Exercism", 5, 7)
#> [1] "cis"
strsplit

Egy stringet R listává bont szét egy elválasztó string alapján. Az elválasztó megadása kötelező (nincs alapértéke), de lehet üres string is.

strsplit("R, Python, Julia", ", ")
[[1]]
#> [1] "R"      "Python" "Julia" 

strsplit("Exercism", "")
[[1]]
#> [1] "E" "x" "e" "r" "c" "i" "s" "m"

A listákról egy külön fogalom szól majd. Ha még nem jutottál el a tantervnek ahhoz a részéhez, egyelőre elég annyit tudnod, hogy az unlist() függvény (ebben az esetben) listát alakít vektorrá.

unlist(strsplit("Exercism", ""))
#> [1] "E" "x" "e" "r" "c" "i" "s" "m"

Tidyverse

Ha jóindulattal akarunk fogalmazni, azt mondhatjuk, hogy a régi stílusú stringfüggvények nem az R legjobbjai (kevésbé jóindulatú vélemények is léteznek).

A helyzet javítására a stringr csomag 2009 óta fejlődik, és mára a Tidyverse gyűjtemény kulcsfontosságú része.

Töltsd be a névtérbe a library(stringr) vagy a library(tidyverse) hívással.

Néhány fontos jellemzője:

  • Minden függvénynév str_ előtaggal kezdődik, és igyekszik világossá tenni a célját.
  • Az argumentumok sorrendje igyekszik következetes lenni, a bemeneti adat az első argumentum.
  • A bemenet lehet egyetlen string vagy összetett adatszerkezet is. A függvények alkalmazkodnak, és a lehető legészszerűbben viselkednek.

Mint minden Tidyverse-csomagnak, a stringr-nek is jó dokumentációja van, amelyet jellemzően a csomag szerzője (szerzői) írt.

Kitérő: gyors bevezetés a pipe-okba

A függvények összekapcsolására szolgáló |> pipe-okról a tanterv más részein lesz szó részletesebben.

Egyelőre ennyit érdemes tudni:

  • A pipe bal oldalán lévő eredmény lesz a jobb oldali függvény első argumentuma (a »jobb oldali« itt az opcionális sortöréseket figyelmen kívül hagyja).
  • A fennmaradó argumentumokat a függvényhívásban adhatod meg.
  • Az R-ben egy függvény_hívásra_ kell pipe-olni, nem csupán egy névre, ezért a zárójelek mindig kötelezők (ez más nyelvekben másképp van).

Az alábbi példa szemlélteti a szintaxist. Az egyes függvényeket később tárgyaljuk.

library(stringr)

"Monday-25-February" |> 
  str_split("-") |>     
  unlist() |>               # [1] "Monday"   "25"       "February"
  str_sub(1, 3) |>          # [1] "Mon" "25"  "Feb"
  str_to_upper() |>         # [1] "MON" "25"  "FEB"
  str_flatten(collapse = ", ")
#> [1] "MON, 25, FEB"
Hosszúságok kezelése

A str_length kódpontokat számol (hasonlóan az nchars-hoz).

Több más függvény is foglalkozik a whitespace-szel, például a str_trim() és a str_squish(). Ez gyakran nélkülözhetetlen tisztítási feladat bármely adatelemzési projekt elején.

# The first 3 kernels in JuPyteR notebooks:
str_length(c("Julia", "Python", "R"))           #> [1] 1 6 5
#> [1] 5 6 1
str_pad(c("Julia", "Python", "R"), 8, "right")  # add spaces if necessary
#> [1] "Julia   " "Python  " "R       "

str_trim("Julia    Python    R    ")   # remove leading & trailing whitespace
#> [1] "Julia    Python    R"
str_squish("Julia   Python  R    ")  # trim, collapse multiple spaces 
#> [1] "Julia Python R"
Részstringek kiválasztása

A str_sub(string, start, end) függvény a start-tól end-ig (a határokat is beleértve) visszaadja a részstringet, míg a str_sub_all() több stringen is működhet.

Nagy a rugalmasság. A start és az end alapértéke az első, illetve az utolsó karakter. Lehetnek indexek vektorai is. Kellemes ellentétben a vektorindexeléssel, a negatív értékek a string végétől számolódnak visszafelé, a Python mintájára.

s <- "abcdefgh"
str_sub(s, 2, 4)
#> [1] "bcd"
str_sub(s, 5)
#> [1] "efgh"
str_sub(s, -3, -2)
#> [1] "fg"
str_sub(s, c(1, 4), c(2, 5))
#> [1] "ab" "de"
str_sub(s, c(1, 4, 6), c(2, 5, -1))
#> [1] "ab"  "de"  "fgh"

s |> str_sub(2, 4) # these functions are designed for pipes
#> [1] "bcd"
Stringek összefűzése

A str_flatten egy karaktervektort alakít egyetlen stringgé. A collapse argumentum minden elem közé bekerül, alapértéke pedig "".

c("R", "Julia", "Python") |> str_flatten()
#> [1] "RJuliaPython"
c("R", "Julia", "Python") |> str_flatten(collapse = " - ")
#> [1] "R - Julia - Python"

A str_c több karaktervektort alakít egyetlen karaktervektorrá, szükség szerinti újrahasznosítással.

str_c(LETTERS[1:8], 1:8, sep = ":")
#> [1] "A:1" "B:2" "C:3" "D:4" "E:5" "F:6" "G:7" "H:8"

A str_glue egyszerű string-interpolációt hoz az R-be. A kapcsos zárójelek { } közötti kifejezések kiértékelődnek, és a szöveges megjelenítésük kerül a helyükre.

r <- 5.3
pi <- 3.14159
str_glue("A circle of radius {r} has area {pi * r^2}")
A circle of radius 5.3 has area 88.2472631
Stringek felbontása

Az R igen gyakori felhasználási módja a rendszertelen adatok egységes formátumra alakítása elemzéshez. Ezt segítendő többféle módon bonthatunk szöveget részstringekre. A legtöbbjük túlmutat a jelenlegi kereteken.

A str_split_1 a legegyszerűbb: egyetlen stringet alakít darabok vektorává, egy megadott minta mentén felbontva (nincs alapértelmezett minta).

s <- "R Julia Python"
str_split_1(s, " ")
#> [1] "R"      "Julia"  "Python"
Stringek módosítása

Egyes nyelvek (főként az európaiak) megkülönböztetik a NAGY- és a kisbetűket. A stringr függvénykészlete ezek átalakítására szolgál, a területi beállításnak megfelelő módon:

  • str_to_lower()
  • str_to_upper()
  • str_to_title() : minden szó első betűje nagybetű
  • str_to_sentence() : a mondat első betűje nagybetű
str_to_upper("elixir")    # defaults to locale = "en"
#> [1] "ELIXIR"
str_to_upper("ελληνικά")  # infers Greek
#> [1] "ΕΛΛΗΝΙΚΆ"

str_to_title("the cat sat on the mat")
#> [1] "The Cat Sat On The Mat"
str_to_sentence("the cat sat on the mat")
#> [1] "The cat sat on the mat"

Mintára illeszkedő részstringek cseréjére a str_replace() a minta első előfordulását cseréli, a str_replace_all() pedig az összeset.

A karakterindexen alapuló részstringcseréhez a str_sub() értékadó változata használható.

 s <- "abcde"
str_sub(s, 3, 4) <- "yz"
s
#> [1] "abyze"

Utasítások

Ebben a feladatban naplósorok feldolgozásával foglalkozsz.

Minden naplósor egy string, amelynek formátuma a következő: "[<LEVEL>]: <MESSAGE>".

Három különböző naplózási szint van:

  • INFO
  • WARNING
  • ERROR

Három részfeladatot kapsz, mindegyik kap egy naplósort, és valamit tenned kell vele.

Szabadon választhatsz, hogy a base R régi függvényeit vagy a stringr csomagot használod, mindkettővel rövid, működő megoldást kaphatsz.

1. Üzenet kinyerése egy naplósorból

Valósítsd meg a message függvényt, amely egy naplósor üzenetét adja vissza:

message("[ERROR]: Invalid operation")
#> "Invalid operation"

A sor elején és végén lévő szóközöket el kell távolítani:

message("[WARNING]:  Disk almost full\r\n")
#> "Disk almost full"

2. Naplózási szint kinyerése egy naplósorból

Valósítsd meg a log_level függvényt, amely egy naplósor naplózási szintjét adja vissza, méghozzá csupa kisbetűvel:

log_level("[ERROR]: Invalid operation")
#> "error"

3. Naplósor újraformázása

Valósítsd meg a reformat függvényt, amely újraformázza a naplósort: az üzenet kerül előre, utána pedig zárójelben a naplózási szint következik:

reformat("[INFO]: Operation completed")
#> "Operation completed (info)"
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
R Exercism

Készen állsz elkezdeni a(z) Logszintek feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) R nyelvet 21 fogalom111 feladat segítségével, valódi emberi mentorálással, mindez ingyen.