texto - Dividir una columna de cadena de marco de datos en mĂșltiples columnas diferentes
separar texto en excel formula (3)
Lo que intento lograr es dividir una columna en múltiples columnas. Preferiría que la primera columna contenga "F", la segunda columna "EE. UU.", La tercera "CA6" o "DL", y la cuarta como "Z13" o "U13", etc. Mi df completo sigue el mismo patrón de X.XX.XXXX.XXX o X.XX.XXX.XXX o X.XX.XX.XXX y sé que la tercera columna es donde reside mi problema debido a las diferentes longitudes. Solo he usado substr en el pasado y podría usarlo aquí con algunas sentencias if pero me gustaría aprender a usar el paquete stringr y POSIX para hacer esto (a menos que haya una mejor opción). Gracias de antemano.
Aquí está mi df:
c("F.US.CLE.V13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13",
"F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13",
"F.US.DL.U13", "F.US.DL.U13", "F.US.DL.U13", "F.US.DL.Z13", "F.US.DL.Z13"
)
¿Es esto lo que estas tratando de hacer?
# Our data
text <- c("F.US.CLE.V13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13",
"F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13", "F.US.CA6.U13",
"F.US.DL.U13", "F.US.DL.U13", "F.US.DL.U13", "F.US.DL.Z13", "F.US.DL.Z13"
)
# Split into individual elements by the ''.'' character
# Remember to escape it, because ''.'' by itself matches any single character
elems <- unlist( strsplit( text , "//." ) )
# We know the dataframe should have 4 columns, so make a matrix
m <- matrix( elems , ncol = 4 , byrow = TRUE )
# Coerce to data.frame - head() is just to illustrate the top portion
head( as.data.frame( m ) )
# V1 V2 V3 V4
#1 F US CLE V13
#2 F US CA6 U13
#3 F US CA6 U13
#4 F US CA6 U13
#5 F US CA6 U13
#6 F US CA6 U13
El camino a través de una unlist
y la matrix
parece un poco intrincado, y requiere que codifique la cantidad de elementos (esto es realmente un no va más grande. Por supuesto, usted podría eludir el código difícil de ese número y determinarlo en tiempo de ejecución )
Iría por una ruta diferente y construiría un marco de datos directamente desde la lista que strsplit
devuelve. Para mí, esto es conceptualmente más simple. Hay esencialmente dos formas de hacer esto:
as.data.frame
- pero dado que la lista es exactamente al revés (tenemos una lista de filas en lugar de una lista de columnas) tenemos que transponer el resultado. Tambiénrownames
losrownames
lasrownames
ya que son feos por defecto (¡pero eso es estrictamente innecesario!):`rownames<-`(t(as.data.frame(strsplit(text, ''//.''))), NULL)
Alternativamente, use
rbind
para construir un marco de datos de la lista de filas. Usamosdo.call
para llamar arbind
con todas las filas como argumentos separados:do.call(rbind, strsplit(text, ''//.''))
Ambas formas producen el mismo resultado:
[,1] [,2] [,3] [,4]
[1,] "F" "US" "CLE" "V13"
[2,] "F" "US" "CA6" "U13"
[3,] "F" "US" "CA6" "U13"
[4,] "F" "US" "CA6" "U13"
[5,] "F" "US" "CA6" "U13"
[6,] "F" "US" "CA6" "U13"
…
Claramente, la segunda forma es mucho más simple que la primera.
Una forma muy directa es simplemente usar read.table
en tu vector de caracteres:
> read.table(text = text, sep = ".", colClasses = "character")
V1 V2 V3 V4
1 F US CLE V13
2 F US CA6 U13
3 F US CA6 U13
4 F US CA6 U13
5 F US CA6 U13
6 F US CA6 U13
7 F US CA6 U13
8 F US CA6 U13
9 F US DL U13
10 F US DL U13
11 F US DL U13
12 F US DL Z13
13 F US DL Z13
colClasses
necesita ser especificado, de lo contrario F
se convierte en FALSE
(que es algo que necesito corregir en "splitstackshape", de lo contrario lo habría recomendado :))
Actualización (> un año después) ...
Alternativamente, puedes usar mi función cSplit
, así:
cSplit(as.data.table(text), "text", ".")
# text_1 text_2 text_3 text_4
# 1: F US CLE V13
# 2: F US CA6 U13
# 3: F US CA6 U13
# 4: F US CA6 U13
# 5: F US CA6 U13
# 6: F US CA6 U13
# 7: F US CA6 U13
# 8: F US CA6 U13
# 9: F US DL U13
# 10: F US DL U13
# 11: F US DL U13
# 12: F US DL Z13
# 13: F US DL Z13
O, separate
de "tidyr", así:
library(dplyr)
library(tidyr)
as.data.frame(text) %>% separate(text, into = paste("V", 1:4, sep = "_"))
# V_1 V_2 V_3 V_4
# 1 F US CLE V13
# 2 F US CA6 U13
# 3 F US CA6 U13
# 4 F US CA6 U13
# 5 F US CA6 U13
# 6 F US CA6 U13
# 7 F US CA6 U13
# 8 F US CA6 U13
# 9 F US DL U13
# 10 F US DL U13
# 11 F US DL U13
# 12 F US DL Z13
# 13 F US DL Z13