Μια συμβολοσειρά είναι ένα κομμάτι κειμένου ανάμεσα σε εισαγωγικά. Κάθε τρέχουσα υποστηριζόμενη έκδοση της 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 που είναι πολύ πιο διαισθητικά, ευέλικτα και αυτοσυνεπή.
Υπάρχει ακόμα πολύς παλιός κώδικας που χρησιμοποιεί συναρτήσεις συμβολοσειρών παλαιού τύπου. Αυτό περιλαμβάνει τις περισσότερες λύσεις της κοινότητας στο Exercism.
Επιπλέον, για μικρές εργασίες μπορεί να είναι χρήσιμο να χρησιμοποιείς ενσωματωμένες συναρτήσεις αντί να εισάγεις μια μεγάλη βιβλιοθήκη. Οι συντηρητές της διαδρομής R τείνουν να ακολουθούν αυτή την προσέγγιση όταν γράφουν υποδειγματικές λύσεις για να επικυρώσουν τις ασκήσεις.
Επομένως, αξίζει ακόμα να μάθεις κάποιες από τις παλιές προσεγγίσεις.
ncharΕπιστρέφει τον αριθμό των χαρακτήρων σε μια συμβολοσειρά.
nchar("string")
#> [1] 6
nchar("Hrōðgār") # a person in Beowulf, written in Old English
#> [1] 7
Το (περίπλοκο!) θέμα του τι σημαίνει "χαρακτήρας" είναι πέρα από το πεδίο μας. Σημείωσε απλώς δύο σημεία στα παραπάνω παραδείγματα:
\0 (κάτι που θα πρόσθετε 1 στο μήκος).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"
Για να είμαστε επιεικείς, θα μπορούσαμε να πούμε ότι οι συναρτήσεις συμβολοσειρών παλαιού τύπου δεν είναι ό,τι καλύτερο έχει να προσφέρει η R (υπάρχουν και λιγότερο επιεικείς απόψεις).
Για να βελτιωθεί η κατάσταση, η βιβλιοθήκη stringr αναπτύσσεται από το 2009 και αποτελεί πλέον βασικό μέρος της συλλογής Tidyverse.
Εισήγαγέ τη στον χώρο ονομάτων σου με library(stringr) ή library(tidyverse).
Μερικά βασικά χαρακτηριστικά περιλαμβάνουν:
str_ και προσπαθούν να κάνουν τον σκοπό τους σαφή.Όπως όλα τα πακέτα του Tidyverse, το stringr έχει καλή τεκμηρίωση, συνήθως γραμμένη από τον/τους δημιουργούς του πακέτου.
Η χρήση σωλήνων |> για τη σύνδεση συναρτήσεων θα συζητηθεί με περισσότερες λεπτομέρειες σε άλλα σημεία του προγράμματος σπουδών.
Για την ώρα, είναι χρήσιμο να ξέρεις ότι:
Το παρακάτω παράδειγμα δείχνει τη σύνταξη. Οι επιμέρους συναρτήσεις θα συζητηθούν αργότερα.
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>".
Υπάρχουν τρία διαφορετικά επίπεδα καταγραφής:
INFOWARNINGERRORΈχεις τρεις εργασίες, καθεμία από τις οποίες παίρνει μια γραμμή καταγραφής και σου ζητά να κάνεις κάτι με αυτήν.
Μπορείς να χρησιμοποιήσεις είτε τις παλιές συναρτήσεις της base R είτε τη βιβλιοθήκη stringr, και οι δύο μπορούν να δώσουν σύντομες και λειτουργικές λύσεις.
Υλοποίησε τη συνάρτηση message ώστε να επιστρέφει το μήνυμα μιας γραμμής καταγραφής:
message("[ERROR]: Invalid operation")
#> "Invalid operation"
Πρέπει να αφαιρείς τυχόν κενά στην αρχή ή στο τέλος:
message("[WARNING]: Disk almost full\r\n")
#> "Disk almost full"
Υλοποίησε τη συνάρτηση log_level ώστε να επιστρέφει το επίπεδο καταγραφής μιας γραμμής καταγραφής, με πεζά γράμματα:
log_level("[ERROR]: Invalid operation")
#> "error"
Υλοποίησε τη συνάρτηση reformat που αναδιαμορφώνει τη γραμμή καταγραφής, βάζοντας πρώτα το μήνυμα και μετά το επίπεδο καταγραφής μέσα σε παρενθέσεις:
reformat("[INFO]: Operation completed")
#> "Operation completed (info)"
Γράψου στο Exercism για να μάθεις και να κατακτήσεις R με 21 έννοιες111 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.