Διαδρομές
/
R
R
/
Ασκήσεις
/
Επίπεδα καταγραφής
Επίπεδα καταγραφής

Επίπεδα καταγραφής

Άσκηση εκμάθησης

Εισαγωγή

Υπόβαθρο

Μια συμβολοσειρά είναι ένα κομμάτι κειμένου ανάμεσα σε εισαγωγικά. Κάθε τρέχουσα υποστηριζόμενη έκδοση της R κωδικοποιεί τις συμβολοσειρές σε UTF-8, οπότε μπορούν να υποστηριχθούν οι περισσότερες γλώσσες του κόσμου.

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

Δυστυχώς, η ορολογία μπορεί να μπερδέψει προγραμματιστές που είναι εξοικειωμένοι με άλλες γλώσσες.

Αν και ο type είναι character, η R δεν κάνει διάκριση ανάμεσα σε ένα μεμονωμένο γράμμα (που ονομάζεται char σε αρκετές άλλες γλώσσες, αλλά όχι στην R) και σε μια μεγάλη συμβολοσειρά. Και τα δύο είναι ένα μεμονωμένο στοιχείο και μπορούν να περικλείονται εναλλάξ σε μονά ' ' ή διπλά " " εισαγωγικά.

Ο οδηγός στυλ συνιστά να χρησιμοποιείς διπλά εισαγωγικά, εκτός αν θέλεις να χρησιμοποιήσεις διπλά εισαγωγικά μέσα στη συμβολοσειρά χωρίς να τα κάνεις escape.

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

Ένα character vector είναι επομένως ένα διάνυσμα συμβολοσειρών, με κάθε συμβολοσειρά ως ένα μεμονωμένο στοιχείο.

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

Στο παραπάνω παράδειγμα, το length(s[1]) είναι ισοδύναμο με το length("some"): ο αριθμός των στοιχείων του διανύσματος, όχι το μήκος της συμβολοσειράς.

Ο χειρισμός μιας μεμονωμένης συμβολοσειράς είναι προφανώς δυνατός, όπως με τη nchar() στο παραπάνω παράδειγμα, αλλά απαιτεί συγκεκριμένες συναρτήσεις που θα συζητήσουμε παρακάτω.

Συναρτήσεις συμβολοσειρών

Τα περισσότερα είναι δυνατά στη βασική R, αλλά πολλοί προγραμματιστές βρίσκουν την υποστήριξη για χειρισμό συμβολοσειρών μάλλον περιορισμένη και μπερδεμένη.

Ευτυχώς, υπάρχουν πακέτα tidyverse που είναι πολύ πιο διαισθητικά, ευέλικτα και αυτοσυνεπή.

Βασική R

Υπάρχει ακόμα πολύς παλιός κώδικας που χρησιμοποιεί συναρτήσεις συμβολοσειρών παλαιού τύπου. Αυτό περιλαμβάνει τις περισσότερες λύσεις της κοινότητας στο Exercism.

Επιπλέον, για μικρές εργασίες μπορεί να είναι χρήσιμο να χρησιμοποιείς ενσωματωμένες συναρτήσεις αντί να εισάγεις μια μεγάλη βιβλιοθήκη. Οι συντηρητές της διαδρομής R τείνουν να ακολουθούν αυτή την προσέγγιση όταν γράφουν υποδειγματικές λύσεις για να επικυρώσουν τις ασκήσεις.

Επομένως, αξίζει ακόμα να μάθεις κάποιες από τις παλιές προσεγγίσεις.

nchar

Επιστρέφει τον αριθμό των χαρακτήρων σε μια συμβολοσειρά.

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

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

Το (περίπλοκο!) θέμα του τι σημαίνει "χαρακτήρας" είναι πέρα από το πεδίο μας. Σημείωσε απλώς δύο σημεία στα παραπάνω παραδείγματα:

  • Αν και υλοποιούνται εσωτερικά σε C, οι συμβολοσειρές στην R δεν τερματίζονται με \0 (κάτι που θα πρόσθετε 1 στο μήκος).
  • Οι χαρακτήρες Unicode πολλαπλών byte αντιμετωπίζονται όπως θα περίμενες/ήλπιζες. Το "Hrōðgār" έχει 7 χαρακτήρες (που ονομάζονται επίσης "runes" ή "σημεία κώδικα"), αλλά χρειάζεται 10 byte για αποθήκευση.
paste και paste0

Συνδυάζει έναν αυθαίρετο αριθμό συμβολοσειρών σε μία συμβολοσειρά.

Προαιρετικά, μπορεί να καθοριστεί ένας διαχωριστής για τη paste: η προεπιλογή είναι ένα κενό.

Το paste0(v) είναι ισοδύναμο με το paste(v, sep = "").

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

Για πιο λεπτομερή έλεγχο της σύνθεσης συμβολοσειρών, η R αντιγράφει τη συνάρτηση sprintf από τη C (και αρκετές μεταγενέστερες γλώσσες: η Wikipedia παραθέτει περίπου 30).

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

Τα κενά διαστήματα στην αρχή ή/και στο τέλος μπορούν να αφαιρεθούν με τη trimws():

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

Υπάρχει μια παράμετρος which = "left" (ή "right") για να αποφύγεις το κόψιμο και στα δύο άκρα.

substr

Λειτουργεί σε μία μόνο συμβολοσειρά και επιστρέφει μια υποσυμβολοσειρά ανάμεσα σε δύο (συμπεριλαμβανόμενα) όρια.

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

Χωρίζει μια συμβολοσειρά σε μια λίστα της R, με βάση μια συμβολοσειρά διαχωρισμού. Ο διαχωριστής είναι υποχρεωτικός (χωρίς προεπιλογή), αλλά μπορεί να είναι μια κενή συμβολοσειρά.

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

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

Οι λίστες θα καλυφθούν σε ξεχωριστή Έννοια. Αν δεν έχεις φτάσει ακόμα σε εκείνο το σημείο του προγράμματος σπουδών, για την ώρα αρκεί να ξέρεις ότι η συνάρτηση unlist() θα μετατρέψει (σε αυτή την περίπτωση) μια λίστα σε διάνυσμα.

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

Tidyverse

Για να είμαστε επιεικείς, θα μπορούσαμε να πούμε ότι οι συναρτήσεις συμβολοσειρών παλαιού τύπου δεν είναι ό,τι καλύτερο έχει να προσφέρει η R (υπάρχουν και λιγότερο επιεικείς απόψεις).

Για να βελτιωθεί η κατάσταση, η βιβλιοθήκη stringr αναπτύσσεται από το 2009 και αποτελεί πλέον βασικό μέρος της συλλογής Tidyverse.

Εισήγαγέ τη στον χώρο ονομάτων σου με library(stringr) ή library(tidyverse).

Μερικά βασικά χαρακτηριστικά περιλαμβάνουν:

  • Όλα τα ονόματα συναρτήσεων έχουν πρόθεμα str_ και προσπαθούν να κάνουν τον σκοπό τους σαφή.
  • Η σειρά των ορισμάτων προσπαθεί να είναι συνεπής, με τα δεδομένα εισόδου ως πρώτο όρισμα.
  • Οι είσοδοι μπορούν να κυμαίνονται από μία μόνο συμβολοσειρά έως σύνθετες δομές δεδομένων. Οι συναρτήσεις θα προσπαθήσουν να προσαρμοστούν και να κάνουν το πιο λογικό.

Όπως όλα τα πακέτα του Tidyverse, το stringr έχει καλή τεκμηρίωση, συνήθως γραμμένη από τον/τους δημιουργούς του πακέτου.

Παρέκβαση: Μια γρήγορη εισαγωγή στους σωλήνες

Η χρήση σωλήνων |> για τη σύνδεση συναρτήσεων θα συζητηθεί με περισσότερες λεπτομέρειες σε άλλα σημεία του προγράμματος σπουδών.

Για την ώρα, είναι χρήσιμο να ξέρεις ότι:

  • Ένα αποτέλεσμα από τα αριστερά του σωλήνα γίνεται το πρώτο όρισμα στη συνάρτηση στα δεξιά (όπου το "δεξιά" αγνοεί τις προαιρετικές αλλαγές γραμμής).
  • Τυχόν υπόλοιπα ορίσματα μπορούν να συμπεριληφθούν στην κλήση της συνάρτησης.
  • Στην R, πρέπει να διοχετεύουμε προς μια κλήση συνάρτησης, όχι απλώς προς ένα όνομα, οπότε οι παρενθέσεις είναι πάντα απαραίτητες (αυτό διαφέρει από ορισμένες άλλες γλώσσες).

Το παρακάτω παράδειγμα δείχνει τη σύνταξη. Οι επιμέρους συναρτήσεις θα συζητηθούν αργότερα.

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"
Διαχείριση μηκών

Η str_length μετρά σημεία κώδικα (παρόμοια με τη nchars).

Διάφορες άλλες συναρτήσεις χειρίζονται τα κενά διαστήματα, όπως οι str_trim() και str_squish(). Αυτή είναι συχνά μια ζωτικής σημασίας εργασία καθαρισμού στην αρχή κάθε έργου επιστήμης δεδομένων.

# 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"
Υποσύνολα συμβολοσειρών

Η συνάρτηση str_sub(string, start, end) θα επιστρέψει την υποσυμβολοσειρά από το start έως το end (συμπεριλαμβανομένων), ενώ η str_sub_all() μπορεί να λειτουργήσει σε πολλές συμβολοσειρές.

Υπάρχει μεγάλη ευελιξία. Τα start και end έχουν ως προεπιλογή τον πρώτο και τον τελευταίο χαρακτήρα, αντίστοιχα. Μπορούν να είναι διανύσματα θέσεων. Σε ευχάριστη αντίθεση με την ευρετηρίαση διανυσμάτων, οι αρνητικές τιμές μετρούν προς τα πίσω από το τέλος της συμβολοσειράς, όπως στην Python.

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"
Συνένωση συμβολοσειρών

Η str_flatten μετατρέπει ένα character vector σε μία συμβολοσειρά. Το όρισμα collapse εισάγεται ανάμεσα σε κάθε στοιχείο και έχει προεπιλογή "".

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

Η str_c μετατρέπει πολλαπλά διανύσματα χαρακτήρων σε ένα μόνο διάνυσμα χαρακτήρων, με ανακύκλωση όπως χρειάζεται.

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"

Η str_glue φέρνει απλή παρεμβολή συμβολοσειρών στην R. Οι εκφράσεις μέσα σε άγκιστρα { } ερμηνεύονται και η αναπαράστασή τους ως κείμενο αντικαθίσταται.

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
Διαχωρισμός συμβολοσειρών

Μια πολύ συνηθισμένη χρήση της R είναι να επεξεργάζεται ακατάστατα δεδομένα ώστε να αποκτήσουν συνεπή μορφή για ανάλυση. Για να βοηθήσει σε αυτό, υπάρχουν αρκετοί τρόποι να χωρίσεις κείμενο σε υποσυμβολοσειρές. Οι περισσότεροι είναι πέρα από το τρέχον πεδίο.

Η str_split_1 είναι η απλούστερη, μετατρέποντας μία μόνο συμβολοσειρά σε διάνυσμα τεμαχίων, χωρισμένο σε κάποιο καθορισμένο μοτίβο (δεν υπάρχει προεπιλεγμένο μοτίβο).

s <- "R Julia Python"
str_split_1(s, " ")
#> [1] "R"      "Julia"  "Python"
Τροποποίηση συμβολοσειρών

Κάποιες γλώσσες (κυρίως ευρωπαϊκές) διακρίνουν ανάμεσα σε ΚΕΦΑΛΑΙΑ και πεζά γράμματα. Υπάρχει ένα σύνολο συναρτήσεων της stringr για τη μεταξύ τους μετατροπή, με τρόπους κατάλληλους για κάθε τοπική ρύθμιση:

  • str_to_lower()
  • str_to_upper()
  • str_to_title() : το πρώτο γράμμα κάθε λέξης σε κεφαλαίο
  • str_to_sentence() : το πρώτο γράμμα της πρότασης σε κεφαλαίο
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"

Για αντικατάσταση υποσυμβολοσειράς με βάση την αντιστοίχιση μοτίβου, η str_replace() αλλάζει την πρώτη εμφάνιση του μοτίβου, ενώ η str_replace_all() αλλάζει όλες τις εμφανίσεις.

Για αντικατάσταση υποσυμβολοσειράς με βάση τις θέσεις χαρακτήρων, υπάρχει μια μορφή εκχώρησης της str_sub().

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

Οδηγίες

Σε αυτή την άσκηση θα επεξεργάζεσαι γραμμές καταγραφής.

Κάθε γραμμή καταγραφής είναι μια συμβολοσειρά με την εξής μορφή: "[<LEVEL>]: <MESSAGE>".

Υπάρχουν τρία διαφορετικά επίπεδα καταγραφής:

  • INFO
  • WARNING
  • ERROR

Έχεις τρεις εργασίες, καθεμία από τις οποίες παίρνει μια γραμμή καταγραφής και σου ζητά να κάνεις κάτι με αυτήν.

Μπορείς να χρησιμοποιήσεις είτε τις παλιές συναρτήσεις της base R είτε τη βιβλιοθήκη stringr, και οι δύο μπορούν να δώσουν σύντομες και λειτουργικές λύσεις.

1. Πάρε το μήνυμα από μια γραμμή καταγραφής

Υλοποίησε τη συνάρτηση message ώστε να επιστρέφει το μήνυμα μιας γραμμής καταγραφής:

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

Πρέπει να αφαιρείς τυχόν κενά στην αρχή ή στο τέλος:

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

2. Πάρε το επίπεδο καταγραφής από μια γραμμή καταγραφής

Υλοποίησε τη συνάρτηση log_level ώστε να επιστρέφει το επίπεδο καταγραφής μιας γραμμής καταγραφής, με πεζά γράμματα:

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

3. Αναδιαμόρφωσε μια γραμμή καταγραφής

Υλοποίησε τη συνάρτηση reformat που αναδιαμορφώνει τη γραμμή καταγραφής, βάζοντας πρώτα το μήνυμα και μετά το επίπεδο καταγραφής μέσα σε παρενθέσεις:

reformat("[INFO]: Operation completed")
#> "Operation completed (info)"
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
R Exercism

Έτοιμος να ξεκινήσεις την άσκηση Επίπεδα καταγραφής;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις R με 21 έννοιες111 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.