Dividir cadenas de texto en R con strsplit()

Manipulación de datos con R Manipulación de texto
La función strsplit() en R

La función strsplit crea subcadenas de una cadena de texto basándose en un separador. En este tutorial aprenderás a utilizar esta función en varios casos de uso.

Sintaxis de strsplit

La función strsplit toma como entrada una cadena o vector de caracteres y un delimitador o separador. La sintaxis básica de la función es la siguiente:

# x: vector de caracteres
# split: delimitador usado para dividir
# fixed: si TRUE, usa 'split' tal cual. Si FALSE (por defecto) 'split' se considera una expresión regular

strsplit(x, split, fixed = FALSE)

El tipo de salida es una lista con la longitud de x y cada elemento de la lista tendrá las subcadenas resultantes de la división.

Dividir una cadena de texto mediante un delimitador

La función strsplit divide cadenas de texto en subcadenas basándose en un delimitador. Por ejemplo, dado un texto puedes dividirlo por espacios pasando la cadena de texto como entrada y un espacio en blanco como delimitador (" ").

strsplit("Esto es un texto", split = " ")
[[1]]
[1] "Esto"  "es"    "un"    "texto"

Cualquier carácter o cadena de texto puede utilizarse como separador y la función lo utilizará para dividir los datos de entrada en subcadenas.

strsplit("Esto&es un texto", split = "&")
[[1]]
[1] "Esto"        "es un texto"

Fíjate que la salida es una lista, por lo que para convertirla en un vector tendrás que deshacer la lista accediendo al elemento correspondiente o utilizando la función unlist.

strsplit("Esto es un texto", split = " ")[[1]]

# Equivalente a:
unlist(strsplit("Esto es un texto", split = " "))
[1] "Esto"  "es"    "un"    "texto"

Ahora podrás acceder a cada subcadena de texto. En los siguientes ejemplos accedemos al primer, segundo y último elemento del texto dividido.

# Obtener el primer elemento
strsplit("Esto es un texto", split = " ")[[1]][1]

# Obtener el segundo elemento
strsplit("Esto es un texto", split = " ")[[1]][2]

# Obtener el último elemento
splitted_string <- strsplit("Esto es un texto", split = " ")[[1]]
splitted_string[length(splitted_string)]
[1] "Esto"  
[1] "es" 
[1] "texto"

La entrada de la función también puede ser un vector de caracteres. En este caso, la salida será una lista con tantos elementos como la longitud de la entrada y cada elemento contendrá las cadenas de texto divididas en función del separador.

strsplit(c("Esto es un texto", "Este es otro texto"), split = " ")
[[1]]
[1] "Esto"  "es"    "un"    "texto"

[[2]]
[1] "Este"  "es"    "otro"  "texto"

Varios delimitadores

La función strsplit puede tomar múltiples separadores si la longitud de x es mayor que uno. En el ejemplo siguiente establecemos un espacio vacío como delimitador de la primera cadena de texto y una barra como delimitador de la segunda. Ten en cuenta que si la longitud del vector de caracteres de entrada es mayor que la longitud de los delimitadores, éstos se reciclarán a lo largo de x.

strsplit(c("Esto es un texto", "Este es/otro texto"), split = c(" ", "/"))
[[1]]
[1] "Esto"  "es"    "un"    "texto"

[[2]]
[1] "Este es"    "otro texto"
strsplit("Texto-con/diferentes&separadores", split = "-|/|&")
[[1]]
[1] "Texto"       "con"         "diferentes"  "separadores"

Dividir una fecha

Un caso de uso habitual de strsplit es dividir una columna de un data frame que contiene fechas en otras tres columnas con el año, mes y día correspondientes. Para ello tendrás que dividir las fechas con "-" o el separador correspondiente, combinar las filas de la salida con rbind y do.call y unir por columnas el resultado en el data frame original.

# Data frame de muestra con fechas
df <- data.frame(date = as.Date(Sys.Date():(Sys.Date() + 5)))

# Dividimos las fechas con "-"
splitted_dates <- strsplit(as.character(df$date), split = "-")

# Combinamos las fechas por filas y las agregamos al data frame
df <- cbind(df, do.call(rbind, splitted_dates))

# Cambiamos los nombres de columna
colnames(df) <- c("Fecha", "Año", "Mes", "Día")
df
       Fecha  Año Mes Día
1 2023-11-19 2023  11  19
2 2023-11-20 2023  11  20
3 2023-11-21 2023  11  21
4 2023-11-22 2023  11  22
5 2023-11-23 2023  11  23
6 2023-11-24 2023  11  24

Uso de expresiones regulares (regex) para dividir caracteres

El argumento split de la función puede tomar expresiones regulares como valor de entrada. Suponiendo que quieres utilizar cualquier número como delimitador podrías pasar "[0-9]" al argumento split.

strsplit("A1B2C3D4", split = "[0-9]")
[[1]]
[1] "A" "B" "C" "D"

Recuerda que si estableces fixed = TRUE la función interpretará el delimitador tal cual, de modo que si, por ejemplo, quieres dividir una cadena por puntos puedes establecer este argumento a TRUE o usar "\\.".

strsplit("Texto.con.puntos", split = ".", fixed = TRUE)

# Equivalente a:
# strsplit("Texto.con.puntos", split = "\\.")
[[1]]
[1] "Texto"  "con"    "puntos"

Si quieres dividir la cadena pero mantener el delimitador puedes usar el siguiente delimitador: "(?<=[DELIMITADORES])" y poner perl = TRUE. Por ejemplo, si quieres utilizar "-" como delimitador y mantenerlo, puedes escribir lo siguiente:

strsplit("a-b-c", split = "(?<=[-])", perl = TRUE)
[[1]]
[1] "a-" "b-" "c"

Lo opuesto a strsplit en R es la función paste. Tendrás que aplicar unlist a la salida y combinarla de nuevo con el mismo delimitador utilizado para la división.

# Dividir cadena de texto por los espacios en blanco
splitted <- strsplit("A B C", split = " ")

# [[1]]
# [1] "A" "B" "C"

# Volver a unir
paste(unlist(splitted), collapse = " ")
# [1] "A B C"