Handhabung spezieller Datentypen

Data Science 1 - Programmieren & Visualisieren

Saskia Otto

Universität Hamburg, IMF

Wintersemester 2023/2024

Lernziele

Am Ende dieser VL- und Übungseinheit werden Sie

  • Faktoren mit den entsprechenden Faktorstufen und sichtbaren Labels erstellen können.
  • Funktionen kennen, um die Reihenfolge der Stufen in z.B. Grafiken zu ändern.
  • wissen, wie das Datum und die Zeit von Computern behandelt wird.
  • als ‘character’ interpretierte Datum- und Zeitangaben in Date und POSIXct Objekte umwandeln können.
  • Datumkomponenten extrahieren können.
  • wissen, wie Strings modifiziert und kombiniert werden können.
  • wissen, wie Muster in Strings gefunden und ersetzt und wie Strings nach Muster aufgeteilt werden können.
  • einen ersten Überblick über reguläre Ausdrücke bei der Zeichenmanipulation haben.

DSB Cheatsheet

Eine komplette Übersicht der wichtigsten Funktionen gibt es hier:

Dieses wie alle anderen DSB Cheatsheets gibt es auf Moodle und der GitHub Repository uham-bio/Cheatsheets.

Kategoriale Variablen als Faktoren

Faktoren in R…

  • sind Vektoren, die nur vorbestimmte Werte (Faktorstufen = ‘levels’) enthalten können,
  • werden verwendet um kategoriale Variablen zu speichern,
  • werden intern mit ganzzahligen Vektoren gebildet und haben 2 Attribute:
    • class ‘factor’ → führt dazu, dass sich der Vektor anders verhält als reguläre ganzzahlige Vektoren
    • levels → definiert das Set an erlaubten Werten

Nachteile eines Zeichenvektors

Stellen Sie sich vor, Sie haben einen Vektor vom Typ ‘character’, der Monate enthält:

x1 <- c("Dec", "Apr", "Jan", "Mar")

Die Verwendung einer Zeichenkette für diese Variable birgt zwei Probleme:


Problem 1

Es findet keine Sortierung in einer hilfreichen Art und Weise statt.

sort(x1)
[1] "Apr" "Dec" "Jan" "Mar"

Problem 2

Es gibt nur zwölf mögliche Monate, und nichts rettet Sie davor Tippfehler zu machen.

x2 <- c("Dec", "Apr", "Jam", "Mar")

Besser: als Faktor konvertieren

→ mit factor()

f1 <- factor(x1)
f1
[1] Dec Apr Jan Mar
Levels: Apr Dec Jan Mar


Dies löst allerdings noch nicht die Probleme…

sort(f1)
[1] Apr Dec Jan Mar
Levels: Apr Dec Jan Mar

→ Wie Sie sehen, werden die einzelnen Faktorstufen (‘levels’) weiterhin alphabetisch sortiert.

Faktoren | levels definieren

Lösung

Übergeben Sie dem Argument levels einen Vektor mit allen gültigen Faktorstufen in gewünschter Reihenfolge.

months <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
f1 <- factor(x1, levels = months)
  • Sie können hier Faktorstufen einfügen, die nicht unbedingt im zu konvertierenden Vektor sein müssen.
  • Jeder Wert, der nicht im Faktorstufen-Vektor ist, wird “leise”” als NA konvertiert.
Problem 1
sort(f1)
[1] Jan Mar Apr Dec
Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
Problem 2
factor(x2, levels = months)
[1] Dec  Apr  <NA> Mar 
Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

Faktoren | levels anzeigen

Um den Satz der gültigen Faktorstufen anzeigen zu lassen, verwenden Sie die FUNKTION levels():

levels(f1)
 [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"

Faktoren | labels definieren

  • Wenn gewünscht, können die Namen der Faktorstufen, die in Grafiken und numerischen Outputs sichtbar sind, umbenannt werden.
  • Dazu einfach einen neuen Vektor dem Argument labels übergeben.
factor(c("Dec", "Apr", "Jan", "Mar"), levels = months, labels = 1:12)
[1] 12 4  1  3 
Levels: 1 2 3 4 5 6 7 8 9 10 11 12
factor(c("Dec", "Apr", "Jan", "Mar"), levels = months, labels = 12:1)
[1] 1  9  12 10
Levels: 12 11 10 9 8 7 6 5 4 3 2 1

Geordnete Faktoren

Wenn kategoriale Variablen ordinal-skaliert sind, dann ist es sinnvoll, einen geordneten Faktor mit dem Argument ordered = TRUE zu erstellen.

→ Hauptunterschied zum normalen Faktor ist die Klasse und die Behandlung von bestimmten Methoden und Funktionen zur Modellanpassung.

x2 <- c(2,1,3,1,1,2)
lab <- c("low","medium","high")
f2 <- factor(x2, levels = 1:3, labels = lab)
o2 <- factor(x2, 1:3, lab, ordered = TRUE)
class(o2)
[1] "ordered" "factor" 

Kontinuierliche Variablen zu Faktoren | 1

  • Mit der Funktion cut(x, breaks) lassen sich kontinuierliche Variablen in Faktoren umwandeln.
  • Die Anzahl der Faktorstufen wird mit dem breaks Argument bestimmt.
x <- 1:4
cut(x, 2)
[1] (0.997,2.5] (0.997,2.5] (2.5,4]     (2.5,4]    
Levels: (0.997,2.5] (2.5,4]

Kontinuierliche Variablen zu Faktoren | 2

Anwendungsbeispiel

iris |>
  mutate(PL_levels = cut(Petal.Length, 4)) |>
  ggplot(aes(Sepal.Length, Sepal.Width, colour = PL_levels)) +
  geom_point() + geom_smooth(method = "lm") +
  guides(colour = guide_legend(title = "Levels of Petal Length"))

Weitere Optionen mit ‘forcats’

Ein hilfreiches ‘tidyverse’ Paket für Faktoren

  • Manuelle Ordnung der Faktorstufen: fct_relevel()
  • Ordnung der Stufen entsprechend
    • ihrer ersten Erscheinung im Datensatz: fct_inorder()
    • ihrer Häufigkeit: fct_infreq()
  • Umgedrehte Reihenfolge der Faktorstufen: fct_rev()
  • Sortierung entlang einer anderen Variable: fct_reorder()
  • Zusammenlegung von Faktorstufen in manuell definierte Gruppen: fct_collapse()

Weitere Optionen mit ‘forcats’ | Demo

Code
p <- bshydro15 |> ggplot() +
  guides(x = guide_axis(angle = 45)) +
  theme(text = element_text(size = 16))

p1 <- p + geom_bar(aes(month)) + ggtitle("Standardeinstellung")
p2 <- p + geom_bar(aes(fct_rev(month))) + ggtitle("fct_rev()")
p3 <- p + geom_bar(aes(fct_infreq(month))) + ggtitle("fct_infreq()")
p4 <- p + geom_bar(aes(fct_collapse(
    month, 
    q1 = c("Jan", "Feb", "Mar"),
    q2 = c("Apr", "May", "Jun"),
    q3 = c("Jul", "Aug", "Sep"),
    q4 = c("Oct", "Nov", "Dec")
  ))) + 
  xlab("annual quarter") +
  ggtitle("fct_collapse()")

gridExtra::grid.arrange(p1,p2,p3,p4, nrow=2)

Your turn …

01:00

Quiz 1-2 | Faktoren

Q1

mantas <- data.frame(
  month = factor(c(9, 3, 5, 1, 7, 12),
    levels = 1:12,
    labels = c('Jan','Feb','Mar','Apr','May','Jun',
      'Jul','Aug','Sep','Oct','Nov','Dec') ),
  catch = c(13,11,26,5,22,8)
)
ggplot(mantas, aes(x = month, y = catch)) +
  geom_col()

Q2

mantas |>
  mutate(month = fct_reorder(
    .f = month, .x = catch)) |>
  ggplot(aes(x = month, y = catch)) +
  geom_col()

Der Umgang mit Datum und Zeit

Zeit ist nicht gleich Zeit

System-interne Zeitspeicherung

Um zu sehen, wie das aktuelle Datum bzw. die aktuelle Zeit Ihres Betriebssystems ist, schauen Sie sich in R Sys.Date() und Sys.time() an:

Sys.Date()
[1] "2024-04-20"
Sys.time()
[1] "2024-04-20 10:52:26 CEST"

→ zuerst kommt Jahr-Monat-Tag (yyyy:mm:dd), dann die Zeit (hh:mm:ss), und dann die Zeitzone (CET = Central European Time).


Wenn Sie folgendes eingeben…

unclass(Sys.Date())
[1] 19833
unclass(Sys.time())
[1] 1713603147

… erhalten Sie die Anzahl der TAGE bzw. SEKUNDEN seit dem 1. Januar 1970 (00:00:00).

Datum und Zeit in R | 3 Klassen

class(Sys.Date())
[1] "Date"
class(Sys.time())
[1] "POSIXct" "POSIXt" 
  • R hat 3 eingebaute Klassen für Datum und Datum-Zeit, auf die Operationen angewendet werden können (siehe ?Ops.Date):
    • Date → repräsentiert nur Kalenderdaten
      • in tibbles auch als <date> deklariert
    • POSIXct (interner Vektor) und POSIXlt (interne Liste) → repräsentieren Kalenderdaten und die Zeit bis zur nächsten Sekunde, einschließlich Zeitzonen (siehe auch ?DateTimeClasses)
      • in tibbles auch als <dttm> deklariert

Das ‘lubridate’ Paket

  • Variablen mit Datum- und Zeitangaben werden beim Import oft nicht automatisch erkannt.
  • Die explizite Definition des Datentyps (Date oder POSIXct) ist aber nützlich, um einzelne Zeitkomponenten später zu extrahieren (z.B. Monat, Jahr, etc.).

lubridate

  • macht es einfacher mit Datum und Uhrzeit zu arbeiten.
  • kann mit einer Vielzahl von unterschiedlichen Formaten umgehen.
  • ist nicht Teil der ‘tidyverse’ Kernpakete. Sprich, es muss einmalig installiert und zusätzlich jedes Mal geladen werden:
install.packages("lubridate")
library(lubridate)

Definition des Datums (Date Objekte)

6 Funktionen zur Auswahl

  • Abhängig von der Reihenfolge der Datumskomponenten gibt es folgende Funktionen:
    • ymd(), ydm(), mdy(), myd(), dmy(), dym()
  • Die Reihenfolge ist entscheidend, das Format wird automatisch erkannt.
  • Die Funktionen können auf einzelne Zeichenketten oder ganze Vektoren angewendet werden.
Beispiele
ymd("2021-11-17") # YEAR-MONTH-DAY
[1] "2021-11-17"
mdy("Nov 17th, 2021") # MONTH-DAY-YEAR
[1] "2021-11-17"
dmy("17-Nov-2021") # DAY-MONTH-YEAR
[1] "2021-11-17"
x <- c("17-Nov-2021", "20-Nov-2021")
dmy(x)
[1] "2021-11-17" "2021-11-20"

Definition von Datum/Zeit (POSIXct)

6 x 3 Möglichkeiten

Kombinieren Sie einfach eine der 6 Datumfunktionen (ymd(), ydm(), mdy(), myd(), dmy(), dym()) mit:

  • _h wenn Sie nur die Stunde haben
  • _hm wenn Sie Stunde und Minuten haben
  • _hms für Stunde-Minute-Sekunde (hour:min:sec)
Beispiele
# Datum mit HOUR
mdy_h("Nov 17th, 2021 13")
[1] "2021-11-17 13:00:00 UTC"
# Datum mit HOUR-MIN
mdy_hm("11/17/2021 12:11")
[1] "2021-11-17 12:11:00 UTC"
# Datum mit HOUR-MIN-SEC
ymd_hms("2021-11-17 12:11:59")
[1] "2021-11-17 12:11:59 UTC"

Spezifikation der Zeitzone

Ist die Zeitzone nicht UTC (‘default’), spezifizieren Sie das tz Argument:

mdy_hm("11/17/2021 12:11", tz = "CET") # CET = Central European Time
[1] "2021-11-17 12:11:00 CET"
OlsonNames() # zeigt eine Liste aller Zeitzonen in R
  [1] "Africa/Abidjan"                   "Africa/Accra"                    
  [3] "Africa/Addis_Ababa"               "Africa/Algiers"                  
  [5] "Africa/Asmara"                    "Africa/Asmera"                   
  [7] "Africa/Bamako"                    "Africa/Bangui"                   
  [9] "Africa/Banjul"                    "Africa/Bissau"                   
 [11] "Africa/Blantyre"                  "Africa/Brazzaville"              
 [13] "Africa/Bujumbura"                 "Africa/Cairo"                    
 [15] "Africa/Casablanca"                "Africa/Ceuta"                    
 [17] "Africa/Conakry"                   "Africa/Dakar"                    
 [19] "Africa/Dar_es_Salaam"             "Africa/Djibouti"                 
 [21] "Africa/Douala"                    "Africa/El_Aaiun"                 
 [23] "Africa/Freetown"                  "Africa/Gaborone"                 
 [25] "Africa/Harare"                    "Africa/Johannesburg"             
 [27] "Africa/Juba"                      "Africa/Kampala"                  
 [29] "Africa/Khartoum"                  "Africa/Kigali"                   
 [31] "Africa/Kinshasa"                  "Africa/Lagos"                    
 [33] "Africa/Libreville"                "Africa/Lome"                     
 [35] "Africa/Luanda"                    "Africa/Lubumbashi"               
 [37] "Africa/Lusaka"                    "Africa/Malabo"                   
 [39] "Africa/Maputo"                    "Africa/Maseru"                   
 [41] "Africa/Mbabane"                   "Africa/Mogadishu"                
 [43] "Africa/Monrovia"                  "Africa/Nairobi"                  
 [45] "Africa/Ndjamena"                  "Africa/Niamey"                   
 [47] "Africa/Nouakchott"                "Africa/Ouagadougou"              
 [49] "Africa/Porto-Novo"                "Africa/Sao_Tome"                 
 [51] "Africa/Timbuktu"                  "Africa/Tripoli"                  
 [53] "Africa/Tunis"                     "Africa/Windhoek"                 
 [55] "America/Adak"                     "America/Anchorage"               
 [57] "America/Anguilla"                 "America/Antigua"                 
 [59] "America/Araguaina"                "America/Argentina/Buenos_Aires"  
 [61] "America/Argentina/Catamarca"      "America/Argentina/ComodRivadavia"
 [63] "America/Argentina/Cordoba"        "America/Argentina/Jujuy"         
 [65] "America/Argentina/La_Rioja"       "America/Argentina/Mendoza"       
 [67] "America/Argentina/Rio_Gallegos"   "America/Argentina/Salta"         
 [69] "America/Argentina/San_Juan"       "America/Argentina/San_Luis"      
 [71] "America/Argentina/Tucuman"        "America/Argentina/Ushuaia"       
 [73] "America/Aruba"                    "America/Asuncion"                
 [75] "America/Atikokan"                 "America/Atka"                    
 [77] "America/Bahia"                    "America/Bahia_Banderas"          
 [79] "America/Barbados"                 "America/Belem"                   
 [81] "America/Belize"                   "America/Blanc-Sablon"            
 [83] "America/Boa_Vista"                "America/Bogota"                  
 [85] "America/Boise"                    "America/Buenos_Aires"            
 [87] "America/Cambridge_Bay"            "America/Campo_Grande"            
 [89] "America/Cancun"                   "America/Caracas"                 
 [91] "America/Catamarca"                "America/Cayenne"                 
 [93] "America/Cayman"                   "America/Chicago"                 
 [95] "America/Chihuahua"                "America/Ciudad_Juarez"           
 [97] "America/Coral_Harbour"            "America/Cordoba"                 
 [99] "America/Costa_Rica"               "America/Creston"                 
[101] "America/Cuiaba"                   "America/Curacao"                 
[103] "America/Danmarkshavn"             "America/Dawson"                  
[105] "America/Dawson_Creek"             "America/Denver"                  
[107] "America/Detroit"                  "America/Dominica"                
[109] "America/Edmonton"                 "America/Eirunepe"                
[111] "America/El_Salvador"              "America/Ensenada"                
[113] "America/Fort_Nelson"              "America/Fort_Wayne"              
[115] "America/Fortaleza"                "America/Glace_Bay"               
[117] "America/Godthab"                  "America/Goose_Bay"               
[119] "America/Grand_Turk"               "America/Grenada"                 
[121] "America/Guadeloupe"               "America/Guatemala"               
[123] "America/Guayaquil"                "America/Guyana"                  
[125] "America/Halifax"                  "America/Havana"                  
[127] "America/Hermosillo"               "America/Indiana/Indianapolis"    
[129] "America/Indiana/Knox"             "America/Indiana/Marengo"         
[131] "America/Indiana/Petersburg"       "America/Indiana/Tell_City"       
[133] "America/Indiana/Vevay"            "America/Indiana/Vincennes"       
[135] "America/Indiana/Winamac"          "America/Indianapolis"            
[137] "America/Inuvik"                   "America/Iqaluit"                 
[139] "America/Jamaica"                  "America/Jujuy"                   
[141] "America/Juneau"                   "America/Kentucky/Louisville"     
[143] "America/Kentucky/Monticello"      "America/Knox_IN"                 
[145] "America/Kralendijk"               "America/La_Paz"                  
[147] "America/Lima"                     "America/Los_Angeles"             
[149] "America/Louisville"               "America/Lower_Princes"           
[151] "America/Maceio"                   "America/Managua"                 
[153] "America/Manaus"                   "America/Marigot"                 
[155] "America/Martinique"               "America/Matamoros"               
[157] "America/Mazatlan"                 "America/Mendoza"                 
[159] "America/Menominee"                "America/Merida"                  
[161] "America/Metlakatla"               "America/Mexico_City"             
[163] "America/Miquelon"                 "America/Moncton"                 
[165] "America/Monterrey"                "America/Montevideo"              
[167] "America/Montreal"                 "America/Montserrat"              
[169] "America/Nassau"                   "America/New_York"                
[171] "America/Nipigon"                  "America/Nome"                    
[173] "America/Noronha"                  "America/North_Dakota/Beulah"     
[175] "America/North_Dakota/Center"      "America/North_Dakota/New_Salem"  
[177] "America/Nuuk"                     "America/Ojinaga"                 
[179] "America/Panama"                   "America/Pangnirtung"             
[181] "America/Paramaribo"               "America/Phoenix"                 
[183] "America/Port_of_Spain"            "America/Port-au-Prince"          
[185] "America/Porto_Acre"               "America/Porto_Velho"             
[187] "America/Puerto_Rico"              "America/Punta_Arenas"            
[189] "America/Rainy_River"              "America/Rankin_Inlet"            
[191] "America/Recife"                   "America/Regina"                  
[193] "America/Resolute"                 "America/Rio_Branco"              
[195] "America/Rosario"                  "America/Santa_Isabel"            
[197] "America/Santarem"                 "America/Santiago"                
[199] "America/Santo_Domingo"            "America/Sao_Paulo"               
[201] "America/Scoresbysund"             "America/Shiprock"                
[203] "America/Sitka"                    "America/St_Barthelemy"           
[205] "America/St_Johns"                 "America/St_Kitts"                
[207] "America/St_Lucia"                 "America/St_Thomas"               
[209] "America/St_Vincent"               "America/Swift_Current"           
[211] "America/Tegucigalpa"              "America/Thule"                   
[213] "America/Thunder_Bay"              "America/Tijuana"                 
[215] "America/Toronto"                  "America/Tortola"                 
[217] "America/Vancouver"                "America/Virgin"                  
[219] "America/Whitehorse"               "America/Winnipeg"                
[221] "America/Yakutat"                  "America/Yellowknife"             
[223] "Antarctica/Casey"                 "Antarctica/Davis"                
[225] "Antarctica/DumontDUrville"        "Antarctica/Macquarie"            
[227] "Antarctica/Mawson"                "Antarctica/McMurdo"              
[229] "Antarctica/Palmer"                "Antarctica/Rothera"              
[231] "Antarctica/South_Pole"            "Antarctica/Syowa"                
[233] "Antarctica/Troll"                 "Antarctica/Vostok"               
[235] "Arctic/Longyearbyen"              "Asia/Aden"                       
[237] "Asia/Almaty"                      "Asia/Amman"                      
[239] "Asia/Anadyr"                      "Asia/Aqtau"                      
[241] "Asia/Aqtobe"                      "Asia/Ashgabat"                   
[243] "Asia/Ashkhabad"                   "Asia/Atyrau"                     
[245] "Asia/Baghdad"                     "Asia/Bahrain"                    
[247] "Asia/Baku"                        "Asia/Bangkok"                    
[249] "Asia/Barnaul"                     "Asia/Beirut"                     
[251] "Asia/Bishkek"                     "Asia/Brunei"                     
[253] "Asia/Calcutta"                    "Asia/Chita"                      
[255] "Asia/Choibalsan"                  "Asia/Chongqing"                  
[257] "Asia/Chungking"                   "Asia/Colombo"                    
[259] "Asia/Dacca"                       "Asia/Damascus"                   
[261] "Asia/Dhaka"                       "Asia/Dili"                       
[263] "Asia/Dubai"                       "Asia/Dushanbe"                   
[265] "Asia/Famagusta"                   "Asia/Gaza"                       
[267] "Asia/Harbin"                      "Asia/Hebron"                     
[269] "Asia/Ho_Chi_Minh"                 "Asia/Hong_Kong"                  
[271] "Asia/Hovd"                        "Asia/Irkutsk"                    
[273] "Asia/Istanbul"                    "Asia/Jakarta"                    
[275] "Asia/Jayapura"                    "Asia/Jerusalem"                  
[277] "Asia/Kabul"                       "Asia/Kamchatka"                  
[279] "Asia/Karachi"                     "Asia/Kashgar"                    
[281] "Asia/Kathmandu"                   "Asia/Katmandu"                   
[283] "Asia/Khandyga"                    "Asia/Kolkata"                    
[285] "Asia/Krasnoyarsk"                 "Asia/Kuala_Lumpur"               
[287] "Asia/Kuching"                     "Asia/Kuwait"                     
[289] "Asia/Macao"                       "Asia/Macau"                      
[291] "Asia/Magadan"                     "Asia/Makassar"                   
[293] "Asia/Manila"                      "Asia/Muscat"                     
[295] "Asia/Nicosia"                     "Asia/Novokuznetsk"               
[297] "Asia/Novosibirsk"                 "Asia/Omsk"                       
[299] "Asia/Oral"                        "Asia/Phnom_Penh"                 
[301] "Asia/Pontianak"                   "Asia/Pyongyang"                  
[303] "Asia/Qatar"                       "Asia/Qostanay"                   
[305] "Asia/Qyzylorda"                   "Asia/Rangoon"                    
[307] "Asia/Riyadh"                      "Asia/Saigon"                     
[309] "Asia/Sakhalin"                    "Asia/Samarkand"                  
[311] "Asia/Seoul"                       "Asia/Shanghai"                   
[313] "Asia/Singapore"                   "Asia/Srednekolymsk"              
[315] "Asia/Taipei"                      "Asia/Tashkent"                   
[317] "Asia/Tbilisi"                     "Asia/Tehran"                     
[319] "Asia/Tel_Aviv"                    "Asia/Thimbu"                     
[321] "Asia/Thimphu"                     "Asia/Tokyo"                      
[323] "Asia/Tomsk"                       "Asia/Ujung_Pandang"              
[325] "Asia/Ulaanbaatar"                 "Asia/Ulan_Bator"                 
[327] "Asia/Urumqi"                      "Asia/Ust-Nera"                   
[329] "Asia/Vientiane"                   "Asia/Vladivostok"                
[331] "Asia/Yakutsk"                     "Asia/Yangon"                     
[333] "Asia/Yekaterinburg"               "Asia/Yerevan"                    
[335] "Atlantic/Azores"                  "Atlantic/Bermuda"                
[337] "Atlantic/Canary"                  "Atlantic/Cape_Verde"             
[339] "Atlantic/Faeroe"                  "Atlantic/Faroe"                  
[341] "Atlantic/Jan_Mayen"               "Atlantic/Madeira"                
[343] "Atlantic/Reykjavik"               "Atlantic/South_Georgia"          
[345] "Atlantic/St_Helena"               "Atlantic/Stanley"                
[347] "Australia/ACT"                    "Australia/Adelaide"              
[349] "Australia/Brisbane"               "Australia/Broken_Hill"           
[351] "Australia/Canberra"               "Australia/Currie"                
[353] "Australia/Darwin"                 "Australia/Eucla"                 
[355] "Australia/Hobart"                 "Australia/LHI"                   
[357] "Australia/Lindeman"               "Australia/Lord_Howe"             
[359] "Australia/Melbourne"              "Australia/North"                 
[361] "Australia/NSW"                    "Australia/Perth"                 
[363] "Australia/Queensland"             "Australia/South"                 
[365] "Australia/Sydney"                 "Australia/Tasmania"              
[367] "Australia/Victoria"               "Australia/West"                  
[369] "Australia/Yancowinna"             "Brazil/Acre"                     
[371] "Brazil/DeNoronha"                 "Brazil/East"                     
[373] "Brazil/West"                      "Canada/Atlantic"                 
[375] "Canada/Central"                   "Canada/Eastern"                  
[377] "Canada/Mountain"                  "Canada/Newfoundland"             
[379] "Canada/Pacific"                   "Canada/Saskatchewan"             
[381] "Canada/Yukon"                     "CET"                             
[383] "Chile/Continental"                "Chile/EasterIsland"              
[385] "CST6CDT"                          "Cuba"                            
[387] "EET"                              "Egypt"                           
[389] "Eire"                             "EST"                             
[391] "EST5EDT"                          "Etc/GMT"                         
[393] "Etc/GMT-0"                        "Etc/GMT-1"                       
[395] "Etc/GMT-10"                       "Etc/GMT-11"                      
[397] "Etc/GMT-12"                       "Etc/GMT-13"                      
[399] "Etc/GMT-14"                       "Etc/GMT-2"                       
[401] "Etc/GMT-3"                        "Etc/GMT-4"                       
[403] "Etc/GMT-5"                        "Etc/GMT-6"                       
[405] "Etc/GMT-7"                        "Etc/GMT-8"                       
[407] "Etc/GMT-9"                        "Etc/GMT+0"                       
[409] "Etc/GMT+1"                        "Etc/GMT+10"                      
[411] "Etc/GMT+11"                       "Etc/GMT+12"                      
[413] "Etc/GMT+2"                        "Etc/GMT+3"                       
[415] "Etc/GMT+4"                        "Etc/GMT+5"                       
[417] "Etc/GMT+6"                        "Etc/GMT+7"                       
[419] "Etc/GMT+8"                        "Etc/GMT+9"                       
[421] "Etc/GMT0"                         "Etc/Greenwich"                   
[423] "Etc/UCT"                          "Etc/Universal"                   
[425] "Etc/UTC"                          "Etc/Zulu"                        
[427] "Europe/Amsterdam"                 "Europe/Andorra"                  
[429] "Europe/Astrakhan"                 "Europe/Athens"                   
[431] "Europe/Belfast"                   "Europe/Belgrade"                 
[433] "Europe/Berlin"                    "Europe/Bratislava"               
[435] "Europe/Brussels"                  "Europe/Bucharest"                
[437] "Europe/Budapest"                  "Europe/Busingen"                 
[439] "Europe/Chisinau"                  "Europe/Copenhagen"               
[441] "Europe/Dublin"                    "Europe/Gibraltar"                
[443] "Europe/Guernsey"                  "Europe/Helsinki"                 
[445] "Europe/Isle_of_Man"               "Europe/Istanbul"                 
[447] "Europe/Jersey"                    "Europe/Kaliningrad"              
[449] "Europe/Kiev"                      "Europe/Kirov"                    
[451] "Europe/Kyiv"                      "Europe/Lisbon"                   
[453] "Europe/Ljubljana"                 "Europe/London"                   
[455] "Europe/Luxembourg"                "Europe/Madrid"                   
[457] "Europe/Malta"                     "Europe/Mariehamn"                
[459] "Europe/Minsk"                     "Europe/Monaco"                   
[461] "Europe/Moscow"                    "Europe/Nicosia"                  
[463] "Europe/Oslo"                      "Europe/Paris"                    
[465] "Europe/Podgorica"                 "Europe/Prague"                   
[467] "Europe/Riga"                      "Europe/Rome"                     
[469] "Europe/Samara"                    "Europe/San_Marino"               
[471] "Europe/Sarajevo"                  "Europe/Saratov"                  
[473] "Europe/Simferopol"                "Europe/Skopje"                   
[475] "Europe/Sofia"                     "Europe/Stockholm"                
[477] "Europe/Tallinn"                   "Europe/Tirane"                   
[479] "Europe/Tiraspol"                  "Europe/Ulyanovsk"                
[481] "Europe/Uzhgorod"                  "Europe/Vaduz"                    
[483] "Europe/Vatican"                   "Europe/Vienna"                   
[485] "Europe/Vilnius"                   "Europe/Volgograd"                
[487] "Europe/Warsaw"                    "Europe/Zagreb"                   
[489] "Europe/Zaporozhye"                "Europe/Zurich"                   
[491] "Factory"                          "GB"                              
[493] "GB-Eire"                          "GMT"                             
[495] "GMT-0"                            "GMT+0"                           
[497] "GMT0"                             "Greenwich"                       
[499] "Hongkong"                         "HST"                             
[501] "Iceland"                          "Indian/Antananarivo"             
[503] "Indian/Chagos"                    "Indian/Christmas"                
[505] "Indian/Cocos"                     "Indian/Comoro"                   
[507] "Indian/Kerguelen"                 "Indian/Mahe"                     
[509] "Indian/Maldives"                  "Indian/Mauritius"                
[511] "Indian/Mayotte"                   "Indian/Reunion"                  
[513] "Iran"                             "Israel"                          
[515] "Jamaica"                          "Japan"                           
[517] "Kwajalein"                        "Libya"                           
[519] "MET"                              "Mexico/BajaNorte"                
[521] "Mexico/BajaSur"                   "Mexico/General"                  
[523] "MST"                              "MST7MDT"                         
[525] "Navajo"                           "NZ"                              
[527] "NZ-CHAT"                          "Pacific/Apia"                    
[529] "Pacific/Auckland"                 "Pacific/Bougainville"            
[531] "Pacific/Chatham"                  "Pacific/Chuuk"                   
[533] "Pacific/Easter"                   "Pacific/Efate"                   
[535] "Pacific/Enderbury"                "Pacific/Fakaofo"                 
[537] "Pacific/Fiji"                     "Pacific/Funafuti"                
[539] "Pacific/Galapagos"                "Pacific/Gambier"                 
[541] "Pacific/Guadalcanal"              "Pacific/Guam"                    
[543] "Pacific/Honolulu"                 "Pacific/Johnston"                
[545] "Pacific/Kanton"                   "Pacific/Kiritimati"              
[547] "Pacific/Kosrae"                   "Pacific/Kwajalein"               
[549] "Pacific/Majuro"                   "Pacific/Marquesas"               
[551] "Pacific/Midway"                   "Pacific/Nauru"                   
[553] "Pacific/Niue"                     "Pacific/Norfolk"                 
[555] "Pacific/Noumea"                   "Pacific/Pago_Pago"               
[557] "Pacific/Palau"                    "Pacific/Pitcairn"                
[559] "Pacific/Pohnpei"                  "Pacific/Ponape"                  
[561] "Pacific/Port_Moresby"             "Pacific/Rarotonga"               
[563] "Pacific/Saipan"                   "Pacific/Samoa"                   
[565] "Pacific/Tahiti"                   "Pacific/Tarawa"                  
[567] "Pacific/Tongatapu"                "Pacific/Truk"                    
[569] "Pacific/Wake"                     "Pacific/Wallis"                  
[571] "Pacific/Yap"                      "Poland"                          
[573] "Portugal"                         "PRC"                             
[575] "PST8PDT"                          "ROC"                             
[577] "ROK"                              "Singapore"                       
[579] "Turkey"                           "UCT"                             
[581] "Universal"                        "US/Alaska"                       
[583] "US/Aleutian"                      "US/Arizona"                      
[585] "US/Central"                       "US/East-Indiana"                 
[587] "US/Eastern"                       "US/Hawaii"                       
[589] "US/Indiana-Starke"                "US/Michigan"                     
[591] "US/Mountain"                      "US/Pacific"                      
[593] "US/Samoa"                         "UTC"                             
[595] "W-SU"                             "WET"                             
[597] "Zulu"                            
attr(,"Version")
[1] "2024a"

Wechseln zwischen den Formaten

Sie können zwischen beiden Formaten mit Hilfe von as_date() und as_datetime() wechseln (es kann aber sein, dass Informationen verloren gehen):

Datum-Uhrzeit Objekt
dt_utc <- mdy_hm("11/17/2021 12:11")
dt_utc
[1] "2021-11-17 12:11:00 UTC"
Umwandlung in ein Datum Objekt
d_utc <- as_date(dt_utc)
d_utc
[1] "2021-11-17"
Zurück zu Datum-Uhrzeit
as_datetime(d_utc)
[1] "2021-11-17 UTC"

Datumskomponenten extrahieren

  • Für Aggregationszwecke ist es häufig hilfreich individuelle Komponenten zu extrahieren.
  • ‘lubridate’ hat folgende Helferfunktionen (alle haben einfach den Namen der Komponente, die extrahiert werden soll):
  • year(), semester(), quarter()
  • month(), week()
  • mday() - day of the month
  • yday() - day of the year
  • wday() - day of the week
  • hour(), minute(), second()
  • tz()
dt_tm <- mdy_hm("11/17/2021 12:11")
year(dt_tm)
[1] 2021
month(dt_tm)
[1] 11
mday(dt_tm)
[1] 17
yday(dt_tm)
[1] 321

Your turn …

02:00

Quiz 3-5 | Datum & Zeit

Q3

Folgender Vektor des Datentyp ‘POSIXcl’ soll in den Datentyp ‘Date’ umgewandelt werden:

d1 
[1] "2015-07-26 18:16:00 UTC" "2015-07-03 16:42:00 UTC"
[3] "2015-09-01 04:45:00 UTC"
d2 <- as_date(d1)
d2 # check
[1] "2015-07-26" "2015-07-03" "2015-09-01"

Q4

Folgender tibble enthält mehrere Datum- bzw. Datum/Zeit-Variablen, die aber alle als ‘character’ Datentyp vorliegen:

tbl
# A tibble: 10 × 5
   x1         x2         x3           x4                  x5              
   <chr>      <chr>      <chr>        <chr>               <chr>           
 1 2015-07-26 2015/26/07 Jul 26, 2015 2015-07-26 18:16:00 26.07.2015T18:16
 2 2015-07-03 2015/03/07 Jul 03, 2015 2015-07-03 16:42:00 03.07.2015T16:42
 3 2015-09-01 2015/01/09 Sep 01, 2015 2015-09-01 04:45:00 01.09.2015T04:45
 4 2015-06-03 2015/03/06 Mar 03, 2015 2015-06-03 08:08:00 03.06.2015T08:08
 5 2015-10-15 2015/15/10 Oct 15, 2015 2015-10-15 21:05:00 15.10.2015T21:05
 6 2015-10-01 2015/01/10 Oct 01, 2015 2015-10-01 10:38:00 01.10.2015T10:38
 7 2015-03-14 2015/14/03 Mar 14, 2015 2015-03-14 05:55:00 14.03.2015T05:55
 8 2015-02-25 2015/25/02 Jun 25, 2015 2015-02-25 08:12:00 25.02.2015T08:12
 9 2015-06-03 2015/03/06 Sep 03, 2015 2015-06-03 11:09:00 03.06.2015T11:09
10 2015-09-14 2015/14/09 Jul 14, 2015 2015-09-14 05:38:00 14.09.2015T05:38
tbl <- mutate(tbl,
  x1 = ymd(x1), x2 = ydm(x2),
  x3 = mdy(x3), x4 = ymd_hms(x4),
  x5 = dmy_hm(x5) )
tbl # check
# A tibble: 10 × 5
   x1         x2         x3         x4                  x5                 
   <date>     <date>     <date>     <dttm>              <dttm>             
 1 2015-07-26 2015-07-26 2015-07-26 2015-07-26 18:16:00 2015-07-26 18:16:00
 2 2015-07-03 2015-07-03 2015-07-03 2015-07-03 16:42:00 2015-07-03 16:42:00
 3 2015-09-01 2015-09-01 2015-09-01 2015-09-01 04:45:00 2015-09-01 04:45:00
 4 2015-06-03 2015-06-03 2015-03-03 2015-06-03 08:08:00 2015-06-03 08:08:00
 5 2015-10-15 2015-10-15 2015-10-15 2015-10-15 21:05:00 2015-10-15 21:05:00
 6 2015-10-01 2015-10-01 2015-10-01 2015-10-01 10:38:00 2015-10-01 10:38:00
 7 2015-03-14 2015-03-14 2015-03-14 2015-03-14 05:55:00 2015-03-14 05:55:00
 8 2015-02-25 2015-02-25 2015-06-25 2015-02-25 08:12:00 2015-02-25 08:12:00
 9 2015-06-03 2015-06-03 2015-09-03 2015-06-03 11:09:00 2015-06-03 11:09:00
10 2015-09-14 2015-09-14 2015-07-14 2015-09-14 05:38:00 2015-09-14 05:38:00

Q5

Aus der Spalte x4 sollen nun folgende Komponenten extrahiert werden: Jahr, Monat, Monatstag, Stunde

tbl2 <- transmute(tbl,
  Jahr = year(tbl$x4), 
  Monat = month(tbl$x4),
  Monatstag = mday(tbl$x4), 
  Stunde = hour(tbl$x4) 
)
tbl2 # check
# A tibble: 10 × 4
    Jahr Monat Monatstag Stunde
   <dbl> <dbl>     <int>  <int>
 1  2015     7        26     18
 2  2015     7         3     16
 3  2015     9         1      4
 4  2015     6         3      8
 5  2015    10        15     21
 6  2015    10         1     10
 7  2015     3        14      5
 8  2015     2        25      8
 9  2015     6         3     11
10  2015     9        14      5

Strings

Was ist nochmal ein ‘string’?

Im Deutschen: Zeichenkette oder Zeichenfolge

  • 2 oder mehr Zeichen (Zahlen, Buchstaben, Schriftzeichen), die in innerhalb eines Paares von einfachen oder doppelten Anführungszeichen geschrieben werden.
  • Variablen oder Vektoren mit Zeichenketten sind in R immer vom Datentyp ‘character’.
Lasst uns ein berühmtes Zitat von Albert Einstein anschauen:
einstein <- c("The difference", 'between stupidity', 
  "and genius is that", 'genius has its limits.')
typeof(einstein)
[1] "character"
length(einstein)
[1] 4

→ Der ‘character’ oder Zeichen-Vektor einstein beinhaltet 4 Elemente oder präziser 4 Zeichenketten.

Manipulation von Zeichenketten | 1

Auch wenn Sie keine aufwendige Textanalyse vorhaben, kann es für Sie hilfreich sein Wissen über die Handhabung und Verarbeitung von Zeichenketten in R zu haben!

Manipulation von Zeichenketten | 2

Und zwar aus folgenden Gründen: Sie möchten ..

  • Spaltennamen ändern (Groß-/Kleinschreibung, Abkürzung)
  • Spalten mit Textdaten wie Stationsnamen oder Artnamen modifizieren:
    • ein bestimmtes Zeichen in den einzelnen Zeichenketten der Variable entfernen
    • einen alten Artnamen mit dem neuen Namen ersetzen
    • bestimmte Kategorien re-klassifizieren, z.B. Zusammenführung verschiedener Lebensstadien in eine Gruppe
  • unnötigen Metadaten im zu importierenden Datensatz entfernen.
  • iterativ sehr viele Dateien mit ähnlichem Dateinamen in R importieren.
  • Daten aus dem Internet extrahieren (‘web-scraping’) und irrelevante Informationen entfernen.

Funktionen für Zeichenketten in R

Basispakete

  • Die R Basispakete sind nicht auf Textverarbeitung ausgelegt und bieten daher nur einige Grundfunktionen an.
  • Neben dem limitierten Umfang an Manipulationsmöglichkeiten haben diese Funktionen auch einige Nachteile, wenn es um die Handhabung von NAs oder das Einfügen von Elementen mit einer Länge von Null geht.
  • Ein Paket, das diese Probleme löst und umfangreiche Funktion zur konsistenten Bearbeitung von Zeichenketten erlaubt, kommt wieder aus der ‘tidyverse’ Welt: stringr
  • Dieses Tutorial gibt Dir nur eine kurze Einführung in einige dieser Funktionen.

Ein weiteres ‘tidyverse’ Paket

In ‘stringr’

  • starten alle Funktionen mit str_, so dass Sie schnell die entsprechende Funktion von der ‘dropdown’ Liste in RStudio auswählen können.
  • sind Argumentnamen (und deren Position) konsistent.
  • behandeln alle Funktionen NA’s und Zeichen mit einer Länge von Null (““) entsprechend.
  • entspricht die Struktur des Outputs jeder Funktion der Struktur des Inputs anderer Funktionen.
Um diese Funktionen nutzen zu können, laden Sie 'stringr' oder 'tidyverse'
library(stringr)
library(tidyverse)

Strings modifizieren | 1

Schreibweise ändern

  • str_to_lower()
    → Umwandlung zu Kleinbuchstaben
  • str_to_upper()
    → Umwandlung zu Großbuchstaben
  • str_to_sentence()
    → erster Buchstabe groß
  • str_to_title()
    → Anfangsbuchstabe jedes Wortes groß
str_to_lower(einstein)
[1] "the difference"         "between stupidity"      "and genius is that"    
[4] "genius has its limits."
str_to_upper(einstein)
[1] "THE DIFFERENCE"         "BETWEEN STUPIDITY"      "AND GENIUS IS THAT"    
[4] "GENIUS HAS ITS LIMITS."
str_to_sentence(einstein)
[1] "The difference"         "Between stupidity"      "And genius is that"    
[4] "Genius has its limits."
str_to_title(einstein)
[1] "The Difference"         "Between Stupidity"      "And Genius Is That"    
[4] "Genius Has Its Limits."

Strings modifizieren | 2

Anwendungsbeispiel

Spaltennamen überschreiben
names(iris) <- str_to_lower(names(iris))
head(iris)
  sepal.length sepal.width petal.length petal.width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

Strings modifizieren | 3

Leerzeichen entfernen

  • str_trim() → Entfernt ‘white space’ am Anfang und Ende einer Zeichenkette.
dat <- read.csv("data/medley.csv")
str(dat)
'data.frame':   34 obs. of  3 variables:
 $ station  : chr  "ER1         " "ER2         " "ER3         " "ER4         " ...
 $ zinc     : chr  "BACK        " "HIGH        " "HIGH        " "MEDIUM      " ...
 $ diversity: num  2.27 1.25 1.15 1.62 1.7 0.63 2.05 1.98 1.04 2.19 ...
unique(dat$zinc)  # uuups
[1] "BACK        " "HIGH        " "MEDIUM      " "LOW         "
dat$zinc <- str_trim(dat$zinc)
unique(dat$zinc)
[1] "BACK"   "HIGH"   "MEDIUM" "LOW"   

Strings kombinieren & nach Position auswählen

Strings kombinieren | 1

  • str_c(..., sep = "", collapse = NULL) → Fügt 2 oder mehr Skalare oder Vektoren (egal welcher Datentyp!) elementweise zu einem einzigen Zeichenvektor bzw. Zeichenkette (!) zusammen.
    • sep → Optionales Trennzeichen zwischen den einzelnen zu verkettenden Elementen.
    • collapse → Trennzeichen zwischen den Elementen des Output Vektors unter weiterer Verkettung zu einem einzigen string.
Mit/ohne 'sep' Argument
# 2 Skalare - Standardeinstellung 
str_c("A", "B")
[1] "AB"
# 2 Skalare - mit Trennzeichen
str_c("A", "B", sep = "/")
[1] "A/B"
# 2 Vektoren - mit Trennzeichen 
str_c(c("A","B"), 1:2, 
  sep = "-")
[1] "A-1" "B-2"
Mit 'collapse' Argument
# 1 Vektor - kollabierend zu 1 string
str_c(c("A","B"), collapse = " + ")
[1] "A + B"
str_c(einstein, collapse = " ")
[1] "The difference between stupidity and genius is that genius has its limits."
# 2 Vektoren - kollabierend zu 1 string
str_c(c("A","B","C"), 1:3, sep = ".", 
  collapse = ", ") 
[1] "A.1, B.2, C.3"

Strings kombinieren | 2

Anwendungsbeispiel 1

Legendentext ändern
iris |> mutate(
  Species = str_c("I. ", Species)) |>
  ggplot(aes(Sepal.Length, Petal.Length)) +
  geom_point(aes(colour = Species)) +
  theme(
    legend.text = element_text(
    face = "italic"), 
    text = element_text(size = 12)
  )

Strings kombinieren | 3

Anwendungsbeispiel 2

Deskriptive Statistiktabelle
iris |> mutate(
  Species = str_c("Iris ", Species)) |>
  group_by(Species) |>
  summarise(
    slm = round(mean(Sepal.Length), 1),
    sls = round(sd(Sepal.Length), 2),
    slms = str_c(slm, sls, sep=" ± ")
  ) |>
  select(Species, slms) |>
  knitr::kable(
    col.names = c("Species", 
      "Mean Sepal Length (± st.dev)")
  ) # erstellt Tabellen in LaTeX, HTML
Species Mean Sepal Length (± st.dev)
Iris setosa 5 ± 0.35
Iris versicolor 5.9 ± 0.52
Iris virginica 6.6 ± 0.64

Nach Position auswählen/ersetzen | 1

  • str_sub(string, start, end) → Extrahiert und ersetzt Teilzeichenketten aus einem Zeichenvektor.
    • start → Optionale Position des ersten Zeichens der zu extrahierenden Teilzeichenketten.
    • end → Optionale Position des letzten Zeichens. Negative Werte zählen von hinten.
Auswählen
x <- c("Shark", "Whale", "Ray")
# Extrahiere erstes Zeichen
str_sub(x, 1, 1)
[1] "S" "W" "R"
# Extrahiere letzes Zeichen
str_sub(x, start = -1) 
[1] "k" "e" "y"
# Extrahiere Zeichen 2-4
str_sub(x, 2, 4) 
[1] "har" "hal" "ay" 
Ersetzen
# Erstes Zeichen ersetzen
str_sub(x, 1, 1) <- "A"
x
[1] "Ahark" "Ahale" "Aay"  
# Funktionen kombinieren
str_sub(x, -1) <- str_sub(x, -1) |> 
  str_to_upper()
x
[1] "AharK" "AhalE" "AaY"  

Nach Position auswählen/ersetzen | 2

Anwendungsbeispiele

Artnamen kürzen
iris |> 
  mutate(Sp_abbr = str_to_upper(
    str_sub(Species, 1, 3))
  ) |>
  select(Species, Sp_abbr) |>
  head()
  Species Sp_abbr
1  setosa     SET
2  setosa     SET
3  setosa     SET
4  setosa     SET
5  setosa     SET
6  setosa     SET
Modellnamen kürzen
lab <- str_sub(rownames(mtcars),1,3)
ggplot(data = mtcars, aes(wt, mpg)) +
  geom_point() +
  geom_text(aes(label=lab), hjust=0, 
    nudge_x = 0.05, colour = "red")

Muster in Zeichenketten

Muster finden | str_detect()

  • str_detect(string, pattern) → Identifiziert Zeichenketten, die ein bestimmtes Muster haben, und gibt einen logischen Vektor zurück.

Überblick der regulären Ausdrücke

  • Einige der Funktionen benötigen reguläre Ausdrücke (‘regex’ oder ‘regexpr’), die eine kurze und prägnante Sprache zur Beschreibung von Mustern in Zeichenketten sind.
  • Um mehr über ‘regex’ zu lernen, empfehle ich die Webseite www.regular-expressions.info, welche viele Beispiele und Tutorials für Einsteiger und Fortgeschrittene bereitstellt.

Adaptiert vom RegEx cheatsheet von Ian Kopacka.

Muster finden | Beispiel Anker

Die Anker (‘anchors’) ^ und $ stehen für die Anfangs- und Endpunkte einer Zeichenkette.

x <- c("shark", "whale shark", "whale", "manta ray", "sting ray")   


Beispiele
str_detect(string = x, pattern = "^w") # = string startet mit 'w'
[1] FALSE  TRUE  TRUE FALSE FALSE
str_detect(x, pattern = "y$") # = string endet mit 'y'
[1] FALSE FALSE FALSE  TRUE  TRUE
str_detect(x, pattern = "whale") # = alle strings die 'whale' enthalten
[1] FALSE  TRUE  TRUE FALSE FALSE
str_detect(x, pattern = "^whale$") # = alle strings die mit 'whale' starten und enden
[1] FALSE FALSE  TRUE FALSE FALSE

Muster finden | Beispiel Zeichenklassen

x <- c("shark", "whale shark", "whale", "whale2", "manta ray", "sting-ray") 
1 Muster
# Enthält ein Leerzeichen (oder " ")
str_detect(x, pattern = "\\s")
[1] FALSE  TRUE FALSE FALSE  TRUE FALSE
# Enthält eine Ziffer
str_detect(x, pattern = "\\d")
[1] FALSE FALSE FALSE  TRUE FALSE FALSE
# Enthält ein Satzzeichen
str_detect(x, pattern = "[[:punct:]]")
[1] FALSE FALSE FALSE FALSE FALSE  TRUE
2 oder mehr Muster
# Endet mit 'ark' ODER 'ale'
str_detect(x, pattern = "(ark|ale)$")
[1]  TRUE  TRUE  TRUE FALSE FALSE FALSE
str_detect(x, pattern = "[ark, ale]$")
[1]  TRUE  TRUE  TRUE FALSE FALSE FALSE
# Startet mit einem Vokal 
str_detect(x, pattern = "^[a,e,i,u,o]") 
[1] FALSE FALSE FALSE FALSE FALSE FALSE

Verwenden Sie den ODER-Operator mit runden Klammern oder das Listenformat ’[Muster1, Muster2,..] wenn nach mehreren Mustern gesucht werden soll.

Nach Muster filtern

  • str_subset() → Wählt Zeichenfolgen aus, die ein bestimmtes Muster enthalten (‘wrapper’ Funktion für x[str_detect(x, pattern)]).
x <- c("shark", "whale shark", "whale", "manta ray", "sting ray")   
# Filtere alle strings in x raus, welche 'ray' enthalten
str_subset(x, "ray")
[1] "manta ray" "sting ray"
# Filtere alle strings in x raus, welche mit einem 'm' starten oder 'k' enden
str_subset(x, "^m|k$")
[1] "shark"       "whale shark" "manta ray"  

Muster austauschen | str_replace()

Muster austauschen | Beispiel

Bereinigen der Spaltennamen
hydro <- read.csv("data/1111473b.csv")
names(hydro)
 [1] "Cruise"                   "Station"                 
 [3] "Type"                     "yyyy.mm.ddThh.mm"        
 [5] "Latitude..degrees_north." "Longitude..degrees_east."
 [7] "Bot..Depth..m."           "PRES..db."               
 [9] "TEMP..deg.C."             "PSAL..psu."              
[11] "DOXY..ml.l."             
names(hydro) <- names(hydro) |>
  str_to_lower() |>
  str_replace(pattern = "\\.$", replacement = "") |>
  str_replace_all(pattern = "\\.+", replacement = "_") 
names(hydro)
 [1] "cruise"                 "station"                "type"                  
 [4] "yyyy_mm_ddthh_mm"       "latitude_degrees_north" "longitude_degrees_east"
 [7] "bot_depth_m"            "pres_db"                "temp_deg_c"            
[10] "psal_psu"               "doxy_ml_l"             

Nach Muster aufteilen | 1

Nach Muster aufteilen | 2

  • str_split(string, pattern, n = Inf, simplify = FALSE) → Spaltet eine Zeichenkette in Teile basierend auf einem spezifischen Muster:
    • n → Anzahl der Teile, die zurückgegeben werden sollen. Standard ist infinity.
    • simplify → Bei FALSE wird eine Matrix zurückgegeben, bei TRUE eine Liste.
Beispiel
fruits <- c("apples and oranges and pears", "pineapples and mangos")
str_split(fruits, " and ", simplify = TRUE) # Matrix-Output
     [,1]         [,2]      [,3]   
[1,] "apples"     "oranges" "pears"
[2,] "pineapples" "mangos"  ""     
# Limitiere die Anzahl der Teile auf 2 und Listen-Output
str_split(fruits, " and ", n = 2, simplify = FALSE)
[[1]]
[1] "apples"            "oranges and pears"

[[2]]
[1] "pineapples" "mangos"    

Anwendungsbeispiel | sharks_fb

Wir wollen aus dem sharks_fb Datensatz im R Paket ‘marinedata’ alle Arten filtern, die auch im Pelagial vorkommen und anschl. den Gattungsnamen in einer Extraspalte abspeichern:

data(sharks_fb, package = "marinedata")
# Hier ist die Information zum Habitattyp:
levels(sharks_fb$DemersPelag)
[1] "pelagic"         "benthopelagic"   "demersal"        "reef-associated"
[5] "bathypelagic"    "bathydemersal"   "pelagic-oceanic" "pelagic-neritic"
sharks_fb |> filter(str_detect(DemersPelag, "pelagic")) |> 
  select(Species, DemersPelag) |>
  mutate(Genus = str_split(Species, " ", n = 2, simplify = TRUE)[ ,1])
# A tibble: 324 × 3
   Species                   DemersPelag     Genus         
   <chr>                     <fct>           <chr>         
 1 Lamna nasus               pelagic-oceanic Lamna         
 2 Cetorhinus maximus        pelagic-oceanic Cetorhinus    
 3 Somniosus microcephalus   benthopelagic   Somniosus     
 4 Squalus acanthias         benthopelagic   Squalus       
 5 Echinorhinus cookei       benthopelagic   Echinorhinus  
 6 Centrophorus tessellatus  benthopelagic   Centrophorus  
 7 Centroscyllium granulatum bathypelagic    Centroscyllium
 8 Centroscyllium nigrum     benthopelagic   Centroscyllium
 9 Etmopterus brachyurus     pelagic-oceanic Etmopterus    
10 Etmopterus bullisi        pelagic-oceanic Etmopterus    
# ℹ 314 more rows

Your turn …

03:00

Quiz 6-8 | Strings

Q6

x
[1] "Placement in the"                    
[2] "genus is provisional pending"        
[3] "the discovery of juvenile specimens."
y <- ...(x)
y
[1] "Placement In The"                    
[2] "Genus Is Provisional Pending"        
[3] "The Discovery Of Juvenile Specimens."

Q7

str_c('A', 1:5, sep = '/')
[1] "A/1" "A/2" "A/3" "A/4" "A/5"

Q8

str_c('A', 1:5, sep = '.', collapse = ' / ')
[1] "A.1 / A.2 / A.3 / A.4 / A.5"

Übungsaufgabe

VL-Skript und Fallstudien

  • Explorieren Sie das VL-begleitende R Skript (in Moodle) und experimentieren Sie mit den Einstellungen.
  • Probieren Sie doch einige der Funktionen zu Faktoren und Zeichenkettenmanipulation in Ihrer Fallstudie aus.

Swirl-Lektionen zur Vertiefung

Kurs DS1-05-Handling spezieller Datentypen

  • L01-Faktoren
  • L02-Faktoren_und_das_forcats_Paket
  • L03-Datum_und_Zeit_in_R
  • L04-Datum_Zeit_und_das_lubridate_Paket
  • L05-Grundfunktionen_zur_Textmanipulation
  • L06-Zeichenketten_und_das_stringr_Paket
  • L07-Textmanipulation_und_regulaere_Ausdruecke

Wie fühlen Sie sich jetzt…?

Total konfus?


Dann empfehle ich Ihnen:

  • Lesen Sie Kapitel 15 über Faktoren in ‘R for Data Science’.
  • Um mehr über die Funktionen zu lernen, die ‘lubridate’ bietet, lesen Sie die Vignette oder Kapitel 16 in ‘R for Data Science’.
  • Kapitel 14 über strings ist lesenswert und mit guten Übungen versehen, um reguläre Ausdrücke zu üben; ebenso die Webseite https://www.regular-expressions.info.
  • Sehen Sie sich auch die Posit/RStudio Cheatsheets an, um einen Überblick über die Funktionen zu bekommen:

Total gelangweilt?

Dann testen Sie doch Ihr Wissen in folgendem Abschlussquiz…

Abschlussquiz

Bei weiteren Fragen: saskia.otto(at)uni-hamburg.de

Creative Commons License
Diese Arbeit is lizenziert unter einer Creative Commons Attribution-ShareAlike 4.0 International License mit Ausnahme der entliehenen und mit Quellenangabe versehenen Abbildungen.