Me gustaría tomar datos del formulario
before = data.frame(attr = c(1,30,4,6), type=c('foo_and_bar','foo_and_bar_2'))
attr type
1 1 foo_and_bar
2 30 foo_and_bar_2
3 4 foo_and_bar
4 6 foo_and_bar_2
y use split()
en la columna " type
" desde arriba para obtener algo como esto:
attr type_1 type_2
1 1 foo bar
2 30 foo bar_2
3 4 foo bar
4 6 foo bar_2
Se me ocurrió algo increíblemente complejo que involucra alguna forma de apply
que funcionó, pero desde entonces lo he perdido. Parecía demasiado complicado para ser la mejor manera. Puedo usarlo a strsplit
continuación, pero luego no está claro cómo volver a colocarlo en 2 columnas en el marco de datos.
> strsplit(as.character(before$type),'_and_')
[[1]]
[1] "foo" "bar"
[[2]]
[1] "foo" "bar_2"
[[3]]
[1] "foo" "bar"
[[4]]
[1] "foo" "bar_2"
Gracias por cualquier puntero. Todavía no he asimilado las listas R.
left_right <- str_split_fixed(as.character(split_df),'\">',2)
str_split_fixed("aaa...bbb", fixed("..."), 2)
funciona bienfixed()
para "Hacer coincidir una cadena fija" en elpattern=
argumento..
significa 'cualquier personaje' en expresiones regulares.Otra opción es usar el nuevo paquete tidyr.
fuente
str_split_fixed
y agregar columnas al marco de datos existente)?5 años después agregando la
data.table
solución obligatoriaTambién podríamos asegurarnos de que las columnas resultantes tengan los tipos correctos y mejorar el rendimiento agregando
type.convert
yfixed
argumentos (ya"_and_"
que no es realmente una expresión regular)fuente
'_and_'
patrones varía, puede averiguar el número máximo de coincidencias (es decir, columnas futuras) conmax(lengths(strsplit(before$type, '_and_')))
strsplit
, crea un solo vector con 2 valores en cada ranura, portstrsplit
lo que lo transpone en 2 vectores con un solo valor en cada uno.paste0
solo se usa para crear los nombres de columna, no se usa en los valores. En el LHS de la ecuación están los nombres de las columnas, en el RHS está la operación de división + transposición en la columna.:=
significa " asignar en el lugar ", por lo tanto, no ve el<-
operador de asignación allí.Otro enfoque: uso
rbind
enout
:Y para combinar:
fuente
strcapture("(.*)_and_(.*)", as.character(before$type), data.frame(type_1 = "", type_2 = ""))
Observe que se puede usar sapply con "[" para extraer el primer o el segundo elemento de esas listas, por lo tanto:
Y aquí hay un método gsub:
fuente
Aquí hay una línea en la misma línea que la solución de Aniko, pero usando el paquete stringr de Hadley:
fuente
stringr
paquete.Para agregar a las opciones, también puede usar mi
splitstackshape::cSplit
función de esta manera:fuente
Una manera fácil es usar
sapply()
y la[
función:Por ejemplo:
sapply()
El resultado es una matriz y necesita transposición y conversión a un marco de datos. Son entonces algunas manipulaciones simples las que producen el resultado que deseabas:En este punto,
after
es lo que queríasfuente
El tema está casi agotado, aunque me gustaría ofrecer una solución a una versión un poco más general en la que no se conoce el número de columnas de salida, a priori. Entonces por ejemplo tienes
No podemos usar dplyr
separate()
porque no sabemos el número de columnas de resultados antes de la división, por lo que he creado una función que utilizastringr
para dividir una columna, dado el patrón y un prefijo de nombre para las columnas generadas. Espero que los patrones de codificación utilizados sean correctos.Luego podemos usar
split_into_multiple
en una tubería dplyr de la siguiente manera:Y luego podemos usar
gather
para ordenar ...fuente
Aquí hay una base R one liner que se superpone a varias soluciones anteriores, pero devuelve un data.frame con los nombres correctos.
Se utiliza
strsplit
para dividir la variable ydata.frame
condo.call
/rbind
para volver a colocar los datos en un data.frame. La mejora incremental adicional es el uso desetNames
agregar nombres de variables al data.frame.fuente
Esta pregunta es bastante antigua, pero agregaré la solución que encontré es la más simple en la actualidad.
fuente
Desde R versión 3.4.0, puede usarlo
strcapture()
desde el paquete utils (incluido con las instalaciones base R), vinculando la salida a la (s) otra (s) columna (s).fuente
Otro enfoque si desea seguir
strsplit()
es utilizar elunlist()
comando. Aquí hay una solución en ese sentido.fuente
base pero probablemente lenta:
fuente
Aquí hay otra solución base R. Podemos usarlo,
read.table
pero dado que solo acepta unsep
argumento de un byte y aquí tenemos un separador de varios bytes que podemos usargsub
para reemplazar el separador de varios bytes a cualquier separador de un byte y usarlo comosep
argumento enread.table
En este caso, también podemos acortarlo reemplazándolo con un
sep
argumento predeterminado para que no tengamos que mencionarlo explícitamentefuente