tabla - ver mapa en arcmap
Columna dividida en el delimitador en el marco de datos (6)
Esta pregunta ya tiene una respuesta aquí:
Me gustaría dividir una columna en dos dentro de un marco de datos basado en un delimitador. Por ejemplo,
a|b
b|c
convertirse
a b
b c
dentro de un marco de datos.
¡Gracias!
@Taesung Shin tiene razón, pero solo un poco más de magia para convertirlo en un data.frame
. Agregué una línea "x | y" para evitar ambigüedades:
df <- data.frame(ID=11:13, FOO=c(''a|b'',''b|c'',''x|y''))
foo <- data.frame(do.call(''rbind'', strsplit(as.character(df$FOO),''|'',fixed=TRUE)))
O bien, si desea reemplazar las columnas en el data.frame existente:
within(df, FOO<-data.frame(do.call(''rbind'', strsplit(as.character(FOO), ''|'', fixed=TRUE))))
Que produce:
ID FOO.X1 FOO.X2
1 11 a b
2 12 b c
3 13 x y
Acabo de encontrar esta pregunta ya que estaba vinculada en una pregunta reciente sobre SO .
Conector desvergonzado: use cSplit
de mi paquete "splitstackshape":
df <- data.frame(ID=11:13, FOO=c(''a|b'',''b|c'',''x|y''))
library(splitstackshape)
cSplit(df, "FOO", "|")
# ID FOO_1 FOO_2
# 1 11 a b
# 2 12 b c
# 3 13 x y
Esta función particular también maneja la división de múltiples columnas, incluso si cada columna tiene un delimitador diferente:
df <- data.frame(ID=11:13,
FOO=c(''a|b'',''b|c'',''x|y''),
BAR = c("A*B", "B*C", "C*D"))
cSplit(df, c("FOO", "BAR"), c("|", "*"))
# ID FOO_1 FOO_2 BAR_1 BAR_2
# 1 11 a b A B
# 2 12 b c B C
# 3 13 x y C D
Básicamente, es una envoltura de conveniencia elegante para usar read.table(text = some_character_vector, sep = some_sep)
y enlazar ese resultado al data.frame
original.En otras palabras, otro enfoque de A base R podría ser:
df <- data.frame(ID=11:13, FOO=c(''a|b'',''b|c'',''x|y''))
cbind(df, read.table(text = as.character(df$FOO), sep = "|"))
ID FOO V1 V2
1 11 a|b a b
2 12 b|c b c
3 13 x|y x y
El recientemente popular paquete tidyr
hace con separate
. Utiliza expresiones regulares, por lo que tendrás que escapar de |
df <- data.frame(ID=11:13, FOO=c(''a|b'', ''b|c'', ''x|y''))
separate(data = df, col = FOO, into = c("left", "right"), sep = "//|")
ID left right
1 11 a b
2 12 b c
3 13 x y
aunque en este caso los valores predeterminados son lo suficientemente inteligentes como para funcionar (busca caracteres no alfanuméricos para dividir).
separate(data = df, col = FOO, into = c("left", "right"))
Hadley tiene una solución muy elegante para hacer esto dentro de los marcos de datos en su paquete de reshape
, usando la función colsplit
.
require(reshape)
> df <- data.frame(ID=11:13, FOO=c(''a|b'',''b|c'',''x|y''))
> df
ID FOO
1 11 a|b
2 12 b|c
3 13 x|y
> df = transform(df, FOO = colsplit(FOO, split = "//|", names = c(''a'', ''b'')))
> df
ID FOO.a FOO.b
1 11 a b
2 12 b c
3 13 x y
La combinación de las respuestas de @Ramnath y @ Tommy me permitió encontrar un enfoque que funciona en la base R para una o más columnas.
Uso básico:
> df = data.frame(
+ id=1:3, foo=c(''a|b'',''b|c'',''c|d''),
+ bar=c(''p|q'', ''r|s'', ''s|t''), stringsAsFactors=F)
> transform(df, test=do.call(rbind, strsplit(foo, ''|'', fixed=TRUE)), stringsAsFactors=F)
id foo bar test.1 test.2
1 1 a|b p|q a b
2 2 b|c r|s b c
3 3 c|d s|t c d
Varias columnas:
> transform(df, lapply(list(foo,bar),
+ function(x)do.call(rbind, strsplit(x, ''|'', fixed=TRUE))), stringsAsFactors=F)
id foo bar X1 X2 X1.1 X2.1
1 1 a|b p|q a b p q
2 2 b|c r|s b c r s
3 3 c|d s|t c d s t
Mejor denominación de múltiples columnas divididas:
> transform(df, lapply({l<-list(foo,bar);names(l)=c(''foo'',''bar'');l},
+ function(x)do.call(rbind, strsplit(x, ''|'', fixed=TRUE))), stringsAsFactors=F)
id foo bar foo.1 foo.2 bar.1 bar.2
1 1 a|b p|q a b p q
2 2 b|c r|s b c r s
3 3 c|d s|t c d s t
strsplit(c(''a|b'',''b|c''),''|'',fixed=TRUE)