Introducción a R

Strings

Introducción

Introducción a la manipulación de cadenas en R.

objetivo: Aprender los conceptos básicos de cómo funcionan las cadenas y cómo crearlas a mano, el enfoque estará en las expresiones regulares o expresiones regulares para abreviar.

Las expresiones regulares son útiles porque las cadenas suelen contener datos no estructurados o semiestructurados, y las expresiones regulares son un lenguaje conciso para describir patrones en cadenas. Cuando mire por primera vez una expresión regular, pensará que un gato caminó sobre su teclado, pero a medida que mejore su comprensión, pronto comenzarán a tener sentido.

usaremos el paquete stringr para la manipulación de cadenas, que forma parte del núcleo tidyverse

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(stringr)

Puede crear cadenas con comillas simples o dobles. Se Recomienda usar siempre “, a menos que desee crear una cadena que contenga varios”.

string1 <- "Esto es un  string"
string2 <- ' Si queremos incluir un es un "espacaio"  denttro de un string usa comilla '
string2
## [1] " Si queremos incluir un es un \"espacaio\"  denttro de un string usa comilla "

Longitud de la cadena

Base R contiene muchas funciones para trabajar con cadenas, pero las evitaremos porque pueden ser inconsistentes, lo que las hace difíciles de recordar. En su lugar, usaremos funciones de stringr.

Estos tienen nombres más intuitivos y todos comienzan con str_. Por ejemplo, str_length() te dice el número de caracteres en una cadena:

str_length(c("a", "R  para cientificos de datos", NA, "Hola a Todos", ""))
## [1]  1 28 NA 12  0
library(gapminder)
library(dplyr)

Combinación de cadenas

Para combinar dos o más cadenas, utilice str_c():

str_c("x", "y")
## [1] "xy"
str_c("Hola", " Bienvenidos", " a una introducion a R")
## [1] "Hola Bienvenidos a una introducion a R"
str_c("x", "y", "z")
## [1] "xyz"

Usa el argumento sep para controlar cómo se separan:

str_c("x", "y", sep = ", ")
## [1] "x, y"
cadena1= "Hola a Todos"
cadena2="Este curso es una introduccion a R"
cadena3= "Paquete stringr"

str_c(cadena1, cadena2, cadena3, sep=", ")
## [1] "Hola a Todos, Este curso es una introduccion a R, Paquete stringr"

Como la mayoría de las otras funciones en R, los valores faltantes son contagiosos. Si desea que se impriman como “NA”, utilice

str_replace_na():

x <- c("abc", NA)
str_c("|-", x, "-|")
## [1] "|-abc-|" NA
str_c("|-", str_replace_na(x), "-|")
## [1] "|-abc-|" "|-NA-|"

Como se muestra arriba, str_c() está vectorizado y recicla automáticamente los vectores más cortos a la misma longitud que el más largo:

str_c("Hola ", c("Juan", "Pedro", "Luis"), c("Como estas", " a", " que taL Todo"))
## [1] "Hola JuanComo estas"    "Hola Pedro a"           "Hola Luis que taL Todo"

Para colapsar un vector de cadenas en una sola cadena, use collapse:

str_c(c("x", "y", "z"), collapse = "; ")
## [1] "x; y; z"

Eliminación de espacios en blanco innecesarios

A menudo, el texto contiene espacios en blanco innecesarios.

blancos <- c("    A la izquierda", "A lña derecha    ", "    ambos lados   ", "   otros     espacios      ")

La eliminación de los que están al principio o al final de una cadena se puede lograr usando str_trim().

str_trim(blancos, side = "left")
## [1] "A la izquierda"           "A lña derecha    "       
## [3] "ambos lados   "           "otros     espacios      "
str_trim(blancos, side = "right")
## [1] "    A la izquierda"    "A lña derecha"         "    ambos lados"      
## [4] "   otros     espacios"
str_trim(blancos) # por defecto
## [1] "A la izquierda"     "A lña derecha"      "ambos lados"       
## [4] "otros     espacios"

str_trim() Sin embargo, no pudo arreglar la última cadena, donde también había espacios en blanco innecesarios entre palabras. Aquí, str_squish es más apropiado. Elimina los espacios en blanco iniciales o finales, así como los duplicados entre palabras

str_squish(blancos)
## [1] "A la izquierda" "A lña derecha"  "ambos lados"    "otros espacios"

Cadenas de subconjuntos

Puede extraer partes de una cadena usando str_sub(). Además de la cadena, str_sub() las start y end argumentos que dan la posición (inclusiva) de la subcadena:

x <- c("Manzana", "Banano", "Pera")
str_sub(x, -2,-1)
## [1] "na" "no" "ra"
str_sub(x, -3, -1)
## [1] "ana" "ano" "era"

Tenga en cuenta que str_sub() no fallará si la cadena es demasiado corta: solo devolverá tanto como sea posible:

str_sub("a", 1, 1000)
## [1] "a"

También puede utilizar el formulario de asignación de str_sub() para modificar cadenas:

str_sub(x, 1) <- str_to_title(str_sub(x, 1)) 
x
## [1] "Manzana" "Banano"  "Pera"
gapminder
## # A tibble: 1,704 × 6
##    country     continent  year lifeExp      pop gdpPercap
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
##  1 Afghanistan Asia       1952    28.8  8425333      779.
##  2 Afghanistan Asia       1957    30.3  9240934      821.
##  3 Afghanistan Asia       1962    32.0 10267083      853.
##  4 Afghanistan Asia       1967    34.0 11537966      836.
##  5 Afghanistan Asia       1972    36.1 13079460      740.
##  6 Afghanistan Asia       1977    38.4 14880372      786.
##  7 Afghanistan Asia       1982    39.9 12881816      978.
##  8 Afghanistan Asia       1987    40.8 13867957      852.
##  9 Afghanistan Asia       1992    41.7 16317921      649.
## 10 Afghanistan Asia       1997    41.8 22227415      635.
## # ℹ 1,694 more rows
gapminder %>% mutate(prim_letras=str_sub(country, 1,3)) %>% mutate(prim_letras=str_to_upper(prim_letras)) 
## # A tibble: 1,704 × 7
##    country     continent  year lifeExp      pop gdpPercap prim_letras
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl> <chr>      
##  1 Afghanistan Asia       1952    28.8  8425333      779. AFG        
##  2 Afghanistan Asia       1957    30.3  9240934      821. AFG        
##  3 Afghanistan Asia       1962    32.0 10267083      853. AFG        
##  4 Afghanistan Asia       1967    34.0 11537966      836. AFG        
##  5 Afghanistan Asia       1972    36.1 13079460      740. AFG        
##  6 Afghanistan Asia       1977    38.4 14880372      786. AFG        
##  7 Afghanistan Asia       1982    39.9 12881816      978. AFG        
##  8 Afghanistan Asia       1987    40.8 13867957      852. AFG        
##  9 Afghanistan Asia       1992    41.7 16317921      649. AFG        
## 10 Afghanistan Asia       1997    41.8 22227415      635. AFG        
## # ℹ 1,694 more rows
gapminder %>% mutate(longitud=str_length(country))
## # A tibble: 1,704 × 7
##    country     continent  year lifeExp      pop gdpPercap longitud
##    <fct>       <fct>     <int>   <dbl>    <int>     <dbl>    <int>
##  1 Afghanistan Asia       1952    28.8  8425333      779.       11
##  2 Afghanistan Asia       1957    30.3  9240934      821.       11
##  3 Afghanistan Asia       1962    32.0 10267083      853.       11
##  4 Afghanistan Asia       1967    34.0 11537966      836.       11
##  5 Afghanistan Asia       1972    36.1 13079460      740.       11
##  6 Afghanistan Asia       1977    38.4 14880372      786.       11
##  7 Afghanistan Asia       1982    39.9 12881816      978.       11
##  8 Afghanistan Asia       1987    40.8 13867957      852.       11
##  9 Afghanistan Asia       1992    41.7 16317921      649.       11
## 10 Afghanistan Asia       1997    41.8 22227415      635.       11
## # ℹ 1,694 more rows

Local

Arriba str_to_lower() cambio el texto a minúsculas. También se puede usar str_to_upper() o str_to_title(). Sin embargo, cambiar de mayúsculas y minúsculas es más complicado de lo que podría parecer a primera vista porque los diferentes idiomas tienen reglas diferentes para cambiar de mayúsculas y minúsculas. Puede elegir qué conjunto de reglas usar especificando una configuración regional:

str_to_upper(c("i", "ı"))
## [1] "I" "I"
str_to_upper(c("i", "ı"), locale = "tr")
## [1] "İ" "I"

La configuración regional se especifica como un código de idioma ISO 639, que es una abreviatura de dos o tres letras. Si aún no conoce el código de su idioma, Wikipedia tiene una buena lista. Si deja la configuración regional en blanco, se utilizará la configuración regional actual, según lo proporcionado por su sistema operativo.

Otra operación importante que se ve afectada por la configuración regional es la clasificación. La base R order()y sort()las funciones ordenan las cadenas utilizando la configuración regional actual. Si desea un comportamiento robusto en diferentes computadoras, es posible que desee usar str_sort()y que toman un argumento str_order()adicional :locale

x <- c("Manzana", "Banano", "Fresa")
str_sort(x, locale = "es")
## [1] "Banano"  "Fresa"   "Manzana"

Ejercicios

  • En sus propias palabras, describa la diferencia entre los argumentos sep y collapse para str_c().

  • Use str_length() y str_sub()para extraer el carácter del medio de una cadena. ¿Qué harás si la cadena tiene un número par de caracteres?

## caso que la longitud sea impar
cadena= "Tomates"
longitud=str_length(cadena)

indice_medio<- (longitud +1)/2

str_sub(cadena, indice_medio, indice_medio )
## [1] "a"
  • ¿Qué str_wrap() hace? ¿Cuándo podrías querer usarlo?
mi_texto="ambio el texto a minúsculas. También se puede usar `str_to_upper()` o `str_to_title()`. Sin embargo, cambiar de mayúsculas y minúsculas es más complicado de lo que podría parecer a primera vista porque los diferentes idiomas tienen reglas diferentes para cambiar de mayúsculas y minúsculas. Puede elegir qué conjunto de reglas usar especificando una configuración regional:"
texto1=str_wrap(mi_texto, width = 20)
texto1
## [1] "ambio el texto a\nminúsculas. También\nse puede usar\n`str_to_upper()` o\n`str_to_title()`.\nSin embargo, cambiar\nde mayúsculas y\nminúsculas es más\ncomplicado de lo\nque podría parecer a\nprimera vista porque\nlos diferentes\nidiomas tienen\nreglas diferentes\npara cambiar\nde mayúsculas y\nminúsculas. Puede\nelegir qué conjunto\nde reglas usar\nespecificando\nuna configuración\nregional:"

Coincidencia de patrones con expresiones regulares

Las expresiones regulares son un lenguaje muy conciso que le permite describir patrones en cadenas.

Para aprender expresiones regulares, usaremos str_view()y str_view_all(). Estas funciones toman un vector de caracteres y una expresión regular y le muestran cómo coinciden.

Patrones básicos

Los patrones más simples coinciden con cadenas exactas:

x <- c("Manzana", "banana", "Pera")
str_view(x, "an")
## [1] │ M<an>z<an>a
## [2] │ b<an><an>a

El siguiente paso en complejidad es ., que coincide con cualquier carácter (excepto una nueva línea):

str_view(x, ".a.")
## [1] │ <Man><zan>a
## [2] │ <ban>ana

Repetición

controlar cuántas veces coincide un patrón:

  • ?: 0 o 1
  • +: 1 o más
  • *: 0 o más
x <- "1888 es el año más largo en números romanos: MDCCCLXXXVIII"
str_view(x, "CC?")
## [1] │ 1888 es el año más largo en números romanos: MD<CC><C>LXXXVIII
str_view(x, "CC+")
## [1] │ 1888 es el año más largo en números romanos: MD<CCC>LXXXVIII
str_view(x, 'C[LX]+')
## [1] │ 1888 es el año más largo en números romanos: MDCC<CLXXX>VIII

También puede especificar el número de coincidencias con precisión:

  • {n}: exactamente n
  • {n,}: n o más
  • {,m}: como mucho m
  • {n,m}: entre n y m
  • str_view(x, “C{2}”)
str_view(x, "C{2}")
## [1] │ 1888 es el año más largo en números romanos: MD<CC>CLXXXVIII
str_view(x, "C{2,}")
## [1] │ 1888 es el año más largo en números romanos: MD<CCC>LXXXVIII
str_view(x, "C{2,3}")
## [1] │ 1888 es el año más largo en números romanos: MD<CCC>LXXXVIII

Detectar coincidencias

Para determinar si un vector de caracteres coincide con un patrón, use str_detect(). Devuelve un vector lógico de la misma longitud que la entrada:

x <- c("apple", "banana", "pear", "pedro")
str_detect(x, "pe")
## [1] FALSE FALSE  TRUE  TRUE
words
##   [1] "a"           "able"        "about"       "absolute"    "accept"     
##   [6] "account"     "achieve"     "across"      "act"         "active"     
##  [11] "actual"      "add"         "address"     "admit"       "advertise"  
##  [16] "affect"      "afford"      "after"       "afternoon"   "again"      
##  [21] "against"     "age"         "agent"       "ago"         "agree"      
##  [26] "air"         "all"         "allow"       "almost"      "along"      
##  [31] "already"     "alright"     "also"        "although"    "always"     
##  [36] "america"     "amount"      "and"         "another"     "answer"     
##  [41] "any"         "apart"       "apparent"    "appear"      "apply"      
##  [46] "appoint"     "approach"    "appropriate" "area"        "argue"      
##  [51] "arm"         "around"      "arrange"     "art"         "as"         
##  [56] "ask"         "associate"   "assume"      "at"          "attend"     
##  [61] "authority"   "available"   "aware"       "away"        "awful"      
##  [66] "baby"        "back"        "bad"         "bag"         "balance"    
##  [71] "ball"        "bank"        "bar"         "base"        "basis"      
##  [76] "be"          "bear"        "beat"        "beauty"      "because"    
##  [81] "become"      "bed"         "before"      "begin"       "behind"     
##  [86] "believe"     "benefit"     "best"        "bet"         "between"    
##  [91] "big"         "bill"        "birth"       "bit"         "black"      
##  [96] "bloke"       "blood"       "blow"        "blue"        "board"      
## [101] "boat"        "body"        "book"        "both"        "bother"     
## [106] "bottle"      "bottom"      "box"         "boy"         "break"      
## [111] "brief"       "brilliant"   "bring"       "britain"     "brother"    
## [116] "budget"      "build"       "bus"         "business"    "busy"       
## [121] "but"         "buy"         "by"          "cake"        "call"       
## [126] "can"         "car"         "card"        "care"        "carry"      
## [131] "case"        "cat"         "catch"       "cause"       "cent"       
## [136] "centre"      "certain"     "chair"       "chairman"    "chance"     
## [141] "change"      "chap"        "character"   "charge"      "cheap"      
## [146] "check"       "child"       "choice"      "choose"      "Christ"     
## [151] "Christmas"   "church"      "city"        "claim"       "class"      
## [156] "clean"       "clear"       "client"      "clock"       "close"      
## [161] "closes"      "clothe"      "club"        "coffee"      "cold"       
## [166] "colleague"   "collect"     "college"     "colour"      "come"       
## [171] "comment"     "commit"      "committee"   "common"      "community"  
## [176] "company"     "compare"     "complete"    "compute"     "concern"    
## [181] "condition"   "confer"      "consider"    "consult"     "contact"    
## [186] "continue"    "contract"    "control"     "converse"    "cook"       
## [191] "copy"        "corner"      "correct"     "cost"        "could"      
## [196] "council"     "count"       "country"     "county"      "couple"     
## [201] "course"      "court"       "cover"       "create"      "cross"      
## [206] "cup"         "current"     "cut"         "dad"         "danger"     
## [211] "date"        "day"         "dead"        "deal"        "dear"       
## [216] "debate"      "decide"      "decision"    "deep"        "definite"   
## [221] "degree"      "department"  "depend"      "describe"    "design"     
## [226] "detail"      "develop"     "die"         "difference"  "difficult"  
## [231] "dinner"      "direct"      "discuss"     "district"    "divide"     
## [236] "do"          "doctor"      "document"    "dog"         "door"       
## [241] "double"      "doubt"       "down"        "draw"        "dress"      
## [246] "drink"       "drive"       "drop"        "dry"         "due"        
## [251] "during"      "each"        "early"       "east"        "easy"       
## [256] "eat"         "economy"     "educate"     "effect"      "egg"        
## [261] "eight"       "either"      "elect"       "electric"    "eleven"     
## [266] "else"        "employ"      "encourage"   "end"         "engine"     
## [271] "english"     "enjoy"       "enough"      "enter"       "environment"
## [276] "equal"       "especial"    "europe"      "even"        "evening"    
## [281] "ever"        "every"       "evidence"    "exact"       "example"    
## [286] "except"      "excuse"      "exercise"    "exist"       "expect"     
## [291] "expense"     "experience"  "explain"     "express"     "extra"      
## [296] "eye"         "face"        "fact"        "fair"        "fall"       
## [301] "family"      "far"         "farm"        "fast"        "father"     
## [306] "favour"      "feed"        "feel"        "few"         "field"      
## [311] "fight"       "figure"      "file"        "fill"        "film"       
## [316] "final"       "finance"     "find"        "fine"        "finish"     
## [321] "fire"        "first"       "fish"        "fit"         "five"       
## [326] "flat"        "floor"       "fly"         "follow"      "food"       
## [331] "foot"        "for"         "force"       "forget"      "form"       
## [336] "fortune"     "forward"     "four"        "france"      "free"       
## [341] "friday"      "friend"      "from"        "front"       "full"       
## [346] "fun"         "function"    "fund"        "further"     "future"     
## [351] "game"        "garden"      "gas"         "general"     "germany"    
## [356] "get"         "girl"        "give"        "glass"       "go"         
## [361] "god"         "good"        "goodbye"     "govern"      "grand"      
## [366] "grant"       "great"       "green"       "ground"      "group"      
## [371] "grow"        "guess"       "guy"         "hair"        "half"       
## [376] "hall"        "hand"        "hang"        "happen"      "happy"      
## [381] "hard"        "hate"        "have"        "he"          "head"       
## [386] "health"      "hear"        "heart"       "heat"        "heavy"      
## [391] "hell"        "help"        "here"        "high"        "history"    
## [396] "hit"         "hold"        "holiday"     "home"        "honest"     
## [401] "hope"        "horse"       "hospital"    "hot"         "hour"       
## [406] "house"       "how"         "however"     "hullo"       "hundred"    
## [411] "husband"     "idea"        "identify"    "if"          "imagine"    
## [416] "important"   "improve"     "in"          "include"     "income"     
## [421] "increase"    "indeed"      "individual"  "industry"    "inform"     
## [426] "inside"      "instead"     "insure"      "interest"    "into"       
## [431] "introduce"   "invest"      "involve"     "issue"       "it"         
## [436] "item"        "jesus"       "job"         "join"        "judge"      
## [441] "jump"        "just"        "keep"        "key"         "kid"        
## [446] "kill"        "kind"        "king"        "kitchen"     "knock"      
## [451] "know"        "labour"      "lad"         "lady"        "land"       
## [456] "language"    "large"       "last"        "late"        "laugh"      
## [461] "law"         "lay"         "lead"        "learn"       "leave"      
## [466] "left"        "leg"         "less"        "let"         "letter"     
## [471] "level"       "lie"         "life"        "light"       "like"       
## [476] "likely"      "limit"       "line"        "link"        "list"       
## [481] "listen"      "little"      "live"        "load"        "local"      
## [486] "lock"        "london"      "long"        "look"        "lord"       
## [491] "lose"        "lot"         "love"        "low"         "luck"       
## [496] "lunch"       "machine"     "main"        "major"       "make"       
## [501] "man"         "manage"      "many"        "mark"        "market"     
## [506] "marry"       "match"       "matter"      "may"         "maybe"      
## [511] "mean"        "meaning"     "measure"     "meet"        "member"     
## [516] "mention"     "middle"      "might"       "mile"        "milk"       
## [521] "million"     "mind"        "minister"    "minus"       "minute"     
## [526] "miss"        "mister"      "moment"      "monday"      "money"      
## [531] "month"       "more"        "morning"     "most"        "mother"     
## [536] "motion"      "move"        "mrs"         "much"        "music"      
## [541] "must"        "name"        "nation"      "nature"      "near"       
## [546] "necessary"   "need"        "never"       "new"         "news"       
## [551] "next"        "nice"        "night"       "nine"        "no"         
## [556] "non"         "none"        "normal"      "north"       "not"        
## [561] "note"        "notice"      "now"         "number"      "obvious"    
## [566] "occasion"    "odd"         "of"          "off"         "offer"      
## [571] "office"      "often"       "okay"        "old"         "on"         
## [576] "once"        "one"         "only"        "open"        "operate"    
## [581] "opportunity" "oppose"      "or"          "order"       "organize"   
## [586] "original"    "other"       "otherwise"   "ought"       "out"        
## [591] "over"        "own"         "pack"        "page"        "paint"      
## [596] "pair"        "paper"       "paragraph"   "pardon"      "parent"     
## [601] "park"        "part"        "particular"  "party"       "pass"       
## [606] "past"        "pay"         "pence"       "pension"     "people"     
## [611] "per"         "percent"     "perfect"     "perhaps"     "period"     
## [616] "person"      "photograph"  "pick"        "picture"     "piece"      
## [621] "place"       "plan"        "play"        "please"      "plus"       
## [626] "point"       "police"      "policy"      "politic"     "poor"       
## [631] "position"    "positive"    "possible"    "post"        "pound"      
## [636] "power"       "practise"    "prepare"     "present"     "press"      
## [641] "pressure"    "presume"     "pretty"      "previous"    "price"      
## [646] "print"       "private"     "probable"    "problem"     "proceed"    
## [651] "process"     "produce"     "product"     "programme"   "project"    
## [656] "proper"      "propose"     "protect"     "provide"     "public"     
## [661] "pull"        "purpose"     "push"        "put"         "quality"    
## [666] "quarter"     "question"    "quick"       "quid"        "quiet"      
## [671] "quite"       "radio"       "rail"        "raise"       "range"      
## [676] "rate"        "rather"      "read"        "ready"       "real"       
## [681] "realise"     "really"      "reason"      "receive"     "recent"     
## [686] "reckon"      "recognize"   "recommend"   "record"      "red"        
## [691] "reduce"      "refer"       "regard"      "region"      "relation"   
## [696] "remember"    "report"      "represent"   "require"     "research"   
## [701] "resource"    "respect"     "responsible" "rest"        "result"     
## [706] "return"      "rid"         "right"       "ring"        "rise"       
## [711] "road"        "role"        "roll"        "room"        "round"      
## [716] "rule"        "run"         "safe"        "sale"        "same"       
## [721] "saturday"    "save"        "say"         "scheme"      "school"     
## [726] "science"     "score"       "scotland"    "seat"        "second"     
## [731] "secretary"   "section"     "secure"      "see"         "seem"       
## [736] "self"        "sell"        "send"        "sense"       "separate"   
## [741] "serious"     "serve"       "service"     "set"         "settle"     
## [746] "seven"       "sex"         "shall"       "share"       "she"        
## [751] "sheet"       "shoe"        "shoot"       "shop"        "short"      
## [756] "should"      "show"        "shut"        "sick"        "side"       
## [761] "sign"        "similar"     "simple"      "since"       "sing"       
## [766] "single"      "sir"         "sister"      "sit"         "site"       
## [771] "situate"     "six"         "size"        "sleep"       "slight"     
## [776] "slow"        "small"       "smoke"       "so"          "social"     
## [781] "society"     "some"        "son"         "soon"        "sorry"      
## [786] "sort"        "sound"       "south"       "space"       "speak"      
## [791] "special"     "specific"    "speed"       "spell"       "spend"      
## [796] "square"      "staff"       "stage"       "stairs"      "stand"      
## [801] "standard"    "start"       "state"       "station"     "stay"       
## [806] "step"        "stick"       "still"       "stop"        "story"      
## [811] "straight"    "strategy"    "street"      "strike"      "strong"     
## [816] "structure"   "student"     "study"       "stuff"       "stupid"     
## [821] "subject"     "succeed"     "such"        "sudden"      "suggest"    
## [826] "suit"        "summer"      "sun"         "sunday"      "supply"     
## [831] "support"     "suppose"     "sure"        "surprise"    "switch"     
## [836] "system"      "table"       "take"        "talk"        "tape"       
## [841] "tax"         "tea"         "teach"       "team"        "telephone"  
## [846] "television"  "tell"        "ten"         "tend"        "term"       
## [851] "terrible"    "test"        "than"        "thank"       "the"        
## [856] "then"        "there"       "therefore"   "they"        "thing"      
## [861] "think"       "thirteen"    "thirty"      "this"        "thou"       
## [866] "though"      "thousand"    "three"       "through"     "throw"      
## [871] "thursday"    "tie"         "time"        "to"          "today"      
## [876] "together"    "tomorrow"    "tonight"     "too"         "top"        
## [881] "total"       "touch"       "toward"      "town"        "trade"      
## [886] "traffic"     "train"       "transport"   "travel"      "treat"      
## [891] "tree"        "trouble"     "true"        "trust"       "try"        
## [896] "tuesday"     "turn"        "twelve"      "twenty"      "two"        
## [901] "type"        "under"       "understand"  "union"       "unit"       
## [906] "unite"       "university"  "unless"      "until"       "up"         
## [911] "upon"        "use"         "usual"       "value"       "various"    
## [916] "very"        "video"       "view"        "village"     "visit"      
## [921] "vote"        "wage"        "wait"        "walk"        "wall"       
## [926] "want"        "war"         "warm"        "wash"        "waste"      
## [931] "watch"       "water"       "way"         "we"          "wear"       
## [936] "wednesday"   "wee"         "week"        "weigh"       "welcome"    
## [941] "well"        "west"        "what"        "when"        "where"      
## [946] "whether"     "which"       "while"       "white"       "who"        
## [951] "whole"       "why"         "wide"        "wife"        "will"       
## [956] "win"         "wind"        "window"      "wish"        "with"       
## [961] "within"      "without"     "woman"       "wonder"      "wood"       
## [966] "word"        "work"        "world"       "worry"       "worse"      
## [971] "worth"       "would"       "write"       "wrong"       "year"       
## [976] "yes"         "yesterday"   "yet"         "you"         "young"
#cuantas plabras empiezan por "t"
sum(str_detect(words, "^t"))
## [1] 65
# ¿Qué proporción de palabras comunes terminan en vocal?
sum(str_detect(words, "[aeiou]$"))
## [1] 271

Sustitución

str_replace() y str_replace_all()le permite reemplazar coincidencias con nuevas cadenas. El uso más simple es reemplazar un patrón con una cadena fija:

x <- c("apple", "pear", "banana")
str_replace(x, "[aeiou]", "-")
## [1] "-pple"  "p-ar"   "b-nana"
str_replace_all(x, "[aeiou]", "-")
## [1] "-ppl-"  "p--r"   "b-n-n-"
str_replace_all(" Vamos Colombia","[aeiou]", "i" )
## [1] " Vimis Cilimbii"

str_replace_all() Puede realizar múltiples reemplazos proporcionando un vector con nombre :

x <- c("1 casa", "2 carros", "3 personas")
str_replace_all(x, c("1" = "una", "2" = "dos", "3" = "tres"))
## [1] "una casa"      "dos carros"    "tres personas"

En lugar de reemplazar con una cadena fija, puede usar referencias inversas para insertar componentes de la coincidencia. En el siguiente código, se invierte el orden de la segunda y la tercera palabra.

head(sentences)
## [1] "The birch canoe slid on the smooth planks." 
## [2] "Glue the sheet to the dark blue background."
## [3] "It's easy to tell the depth of a well."     
## [4] "These days a chicken leg is a rare dish."   
## [5] "Rice is often served in round bowls."       
## [6] "The juice of lemons makes fine punch."
sentences %>% 
  str_replace("([^ ]+) ([^ ]+) ([^ ]+)", "\\1 \\3 \\2") %>% 
  head(5)
## [1] "The canoe birch slid on the smooth planks." 
## [2] "Glue sheet the to the dark blue background."
## [3] "It's to easy tell the depth of a well."     
## [4] "These a days chicken leg is a rare dish."   
## [5] "Rice often is served in round bowls."

División

Úse str_split() para dividir una cuerda en pedazos.

sentences %>%
  head(5) %>% 
  str_split(" ")
## [[1]]
## [1] "The"     "birch"   "canoe"   "slid"    "on"      "the"     "smooth" 
## [8] "planks."
## 
## [[2]]
## [1] "Glue"        "the"         "sheet"       "to"          "the"        
## [6] "dark"        "blue"        "background."
## 
## [[3]]
## [1] "It's"  "easy"  "to"    "tell"  "the"   "depth" "of"    "a"     "well."
## 
## [[4]]
## [1] "These"   "days"    "a"       "chicken" "leg"     "is"      "a"      
## [8] "rare"    "dish."  
## 
## [[5]]
## [1] "Rice"   "is"     "often"  "served" "in"     "round"  "bowls."

Debido a que cada componente puede contener un número diferente de piezas, esto devuelve una lista. Si está trabajando con un vector de longitud 1, lo más fácil es simplemente extraer el primer elemento de la lista:

"a|b|c|d" %>% str_split("\\|") %>% 
  .[[1]]
## [1] "a" "b" "c" "d"

De lo contrario, al igual que las otras funciones stringr que devuelven una lista, puede usar simplify = TRUE para devolver una matriz:

sentences %>%
  head(5) %>% 
  str_split(" ", simplify = TRUE)
##      [,1]    [,2]    [,3]    [,4]      [,5]  [,6]    [,7]     [,8]         
## [1,] "The"   "birch" "canoe" "slid"    "on"  "the"   "smooth" "planks."    
## [2,] "Glue"  "the"   "sheet" "to"      "the" "dark"  "blue"   "background."
## [3,] "It's"  "easy"  "to"    "tell"    "the" "depth" "of"     "a"          
## [4,] "These" "days"  "a"     "chicken" "leg" "is"    "a"      "rare"       
## [5,] "Rice"  "is"    "often" "served"  "in"  "round" "bowls." ""           
##      [,9]   
## [1,] ""     
## [2,] ""     
## [3,] "well."
## [4,] "dish."
## [5,] ""

También puede solicitar un número máximo de piezas:

fields <- c("Nombre: @Ricardo", "Pais: COL", "Edad : 35")
fields %>% str_split("[:@]", n = 3, simplify = TRUE)
##      [,1]     [,2]   [,3]     
## [1,] "Nombre" " "    "Ricardo"
## [2,] "Pais"   " COL" ""       
## [3,] "Edad "  " 35"  ""

En lugar de dividir cadenas por patrones, también puede dividirlas por carácter, línea, oración y palabra boundary():

x <- "Esta es una oración . Esta es otra frase."
str_view_all(x, boundary("word"))
## Warning: `str_view()` was deprecated in stringr 1.5.0.
## ℹ Please use `str_view_all()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## [1] │ <Esta> <es> <una> <oración> . <Esta> <es> <otra> <frase>.

Ejemplo

Apliquemos más conceptos de Stringr a un cuerpo de texto. ¿Dónde podemos encontrar texto? ¿Cómo introduciríamos texto en R?

  • Una forma sería un ‘web scraping’, tomando programáticamente todo el texto relevante de una página, o una serie de páginas, piense en las reseñas de productos de Amazon.

  • Otra sería importar un cuerpo de texto, como un archivo .txt, a R y luego dividirlo en palabras individuales

  • Una tercera forma sería utilizar los datos incluidos en un paquete R. Más comúnmente, los paquetes le brindan acceso a conjuntos de datos en línea demasiado grandes para descargar (Spotify, The New York Times, etc.). Esta técnica, de descargar selectivamente datos relevantes de una base de datos en línea mucho más grande, es la base del concepto de una ‘API’ [Interfaz de programación de aplicaciones, si se lo está preguntando.] Muchos sitios web también usan API, con archivos descargables para análisis.

babynames=babynames::babynames
babynames
## # A tibble: 1,924,665 × 5
##     year sex   name          n   prop
##    <dbl> <chr> <chr>     <int>  <dbl>
##  1  1880 F     Mary       7065 0.0724
##  2  1880 F     Anna       2604 0.0267
##  3  1880 F     Emma       2003 0.0205
##  4  1880 F     Elizabeth  1939 0.0199
##  5  1880 F     Minnie     1746 0.0179
##  6  1880 F     Margaret   1578 0.0162
##  7  1880 F     Ida        1472 0.0151
##  8  1880 F     Alice      1414 0.0145
##  9  1880 F     Bertha     1320 0.0135
## 10  1880 F     Sarah      1288 0.0132
## # ℹ 1,924,655 more rows

Usemos str_detect() para encontrar todos los nombres que incluyen un sonido ‘sh’:

Como puede ver, str_detect() se ejecuta como un operador booleano, ya que asigna un valor VERDADERO o FALSO para cada entrada en la columna, según nuestra declaración condicional: ¿hay una “sh” en la cadena de caracteres?

library(ggplot2)
library(dplyr)
babynames %>% 
  filter(str_detect(name, "Sh") & sex=="F" & year == 1938) %>% 
  arrange(desc(prop)) %>% 
  head(20) %>% 
  ggplot(aes(reorder(name,prop),prop,  fill = name)) + 
  geom_col() +
  coord_flip()

babynames %>% 
  filter(str_detect(name, "Sh") & sex=="F" & year == 1938) %>% 
  arrange(desc(prop)) %>% 
  head(20) %>% 
  mutate(percent = (prop * 100)) %>% 
  ggplot(aes(reorder(name,percent),percent,  fill = name)) + 
  geom_col() +
  coord_flip()

¿Cuántos nombres ‘z’ desde 2000?

babynames %>% 
  filter(year > 2000 & str_detect(name, "Z")) %>% 
  arrange(desc(prop))
## # A tibble: 13,018 × 5
##     year sex   name        n    prop
##    <dbl> <chr> <chr>   <int>   <dbl>
##  1  2001 M     Zachary 18186 0.00880
##  2  2002 M     Zachary 16622 0.00805
##  3  2003 M     Zachary 15539 0.00740
##  4  2004 M     Zachary 13711 0.00649
##  5  2005 M     Zachary 12283 0.00578
##  6  2006 M     Zachary 11005 0.00502
##  7  2007 M     Zachary 10212 0.00461
##  8  2008 M     Zachary  9226 0.00424
##  9  2012 F     Zoey     7466 0.00386
## 10  2009 M     Zachary  8078 0.00381
## # ℹ 13,008 more rows

¿Por qué R solo sacó los nombres que comienzan con Z? Porque lo capitalizamos. ¿Cómo conseguimos ambos?

babynames %>% 
      mutate(Z = str_count(babynames$name, "[zZ]")) %>% 
      arrange(desc(prop))
## # A tibble: 1,924,665 × 6
##     year sex   name        n   prop     Z
##    <dbl> <chr> <chr>   <int>  <dbl> <int>
##  1  1880 M     John     9655 0.0815     0
##  2  1881 M     John     8769 0.0810     0
##  3  1880 M     William  9532 0.0805     0
##  4  1883 M     John     8894 0.0791     0
##  5  1881 M     William  8524 0.0787     0
##  6  1882 M     John     9557 0.0783     0
##  7  1884 M     John     9388 0.0765     0
##  8  1882 M     William  9298 0.0762     0
##  9  1886 M     John     9026 0.0758     0
## 10  1885 M     John     8756 0.0755     0
## # ℹ 1,924,655 more rows
babynames %>% 
      mutate(Z = str_count(babynames$name, "[zZ]")) %>% 
      arrange(desc(Z))
## # A tibble: 1,924,665 × 6
##     year sex   name       n       prop     Z
##    <dbl> <chr> <chr>  <int>      <dbl> <int>
##  1  2010 M     Zzyzx      5 0.00000244     3
##  2  1880 F     Lizzie   388 0.00398        2
##  3  1880 F     Kizzie    13 0.000133       2
##  4  1881 F     Lizzie   396 0.00401        2
##  5  1881 F     Kizzie     9 0.0000910      2
##  6  1882 F     Lizzie   495 0.00428        2
##  7  1882 F     Kizzie     9 0.0000778      2
##  8  1882 F     Dezzie     5 0.0000432      2
##  9  1883 F     Lizzie   496 0.00413        2
## 10  1883 F     Kizzie    14 0.000117       2
## # ℹ 1,924,655 more rows
letra_first=babynames %>% mutate(primera_letra=str_sub(name, 1,1))
letra_first
## # A tibble: 1,924,665 × 6
##     year sex   name          n   prop primera_letra
##    <dbl> <chr> <chr>     <int>  <dbl> <chr>        
##  1  1880 F     Mary       7065 0.0724 M            
##  2  1880 F     Anna       2604 0.0267 A            
##  3  1880 F     Emma       2003 0.0205 E            
##  4  1880 F     Elizabeth  1939 0.0199 E            
##  5  1880 F     Minnie     1746 0.0179 M            
##  6  1880 F     Margaret   1578 0.0162 M            
##  7  1880 F     Ida        1472 0.0151 I            
##  8  1880 F     Alice      1414 0.0145 A            
##  9  1880 F     Bertha     1320 0.0135 B            
## 10  1880 F     Sarah      1288 0.0132 S            
## # ℹ 1,924,655 more rows
letra_first %>% count(primera_letra, sort = TRUE) %>% 
  ggplot(aes(reorder(primera_letra,n), n))+
  geom_col(fill="steelblue")+
  coord_flip()