Separe las filas en columnas con el primer carácter dividido


8

Tener un marco de datos como este:

data.frame(text = c("separate1: and: more","another 20: 42")

¿Cómo es posible separar usando el primero: en cada fila? Ejemplo de salida esperada

data.frame(text1 = c("separate1","another 20"), text2 = c("and: more","42")


2
@ClaudiuPapasteri no. Eso no es exactamente lo mismo y el hecho de que la solución aceptada funcione aquí es accidental. Duplicar con lo que sugieres puede ser muy engañoso
Sotos

@Sotos sí, tienes razón. No estaba prestando atención, dos de las soluciones funcionan pero casualmente. Lo siento por eso. Agregué mis dos centavos al grupo de soluciones como disculpa por un indicador incorrecto.
Claudiu Papasteri

Respuestas:


4
library(reshape2)

df <- data.frame(text = c("separate1: and: more","another 20: 42")

colsplit(df$text, ":", c("text1", "text2"))

5

En la base , puede usar regexprpara encontrar la posición del primero :que puede usarse para extraer subcadenas y trimwseliminar espacios en blanco.

x <- c("separate1: and: more","another 20: 42")

i <- regexpr(":", x)
data.frame(text1 = trimws(substr(x, 1, i-1)), text2 = trimws(substring(x, i+1)))
#       text1     text2
#1  separate1 and: more
#2 another 20        42

4

Se puede utilizar str_split_fixedde stringrpaquete que va por división de valor en el primer delimitador, es decir,

stringr::str_split_fixed(d1$text, ':', 2)

#     [,1]         [,2]        
#[1,] "separate1"  " and: more"
#[2,] "another 20" " 42"       

4
df <- data.frame(text = c("separate1: and: more","another 20: 42"))

df$text1 <- gsub(':.*', '', df$text)
df$text2 <- gsub('^[^:]+: ', '', df$text)

df
#                   text      text1     text2
# 1 separate1: and: more  separate1 and: more
# 2       another 20: 42 another 20        42

4

Usando tidyr :

library(dplyr)
library(tidyr)

df %>% 
  separate(text, c("a", "b"), sep = ": ", extra = "merge")
#            a         b
# 1  separate1 and: more
# 2 another 20        42

3

Otra solución base R

df <- do.call(rbind,lapply(as.character(df$text), function(x) {
  k <- head(unlist(gregexpr(":",x)),1)
  data.frame(text1 = substr(x,1,k-1),
             text2 = substr(x,k+1,nchar(x)))
}))

tal que

> df
       text1      text2
1  separate1  and: more
2 another 20         42

2

Lo sentimos, @Sotos tiene razón, esto no es un duplicado. Aquí hay otra solución base que se divide en la primera aparición del delimitador.

df <- data.frame(text = c("separate1: and: more","another 20: 42"))

list <- apply(df, 1, function(x) regmatches(x, regexpr(":", x), invert = TRUE))
df <- data.frame(matrix(unlist(list), nrow = length(list), byrow = TRUE))

df
#>           X1         X2
#> 1  separate1  and: more
#> 2 another 20         42

Creado el 10/02/2020 por el paquete reprex (v0.2.1)


2

Pobre de edad ?utils::strcapturenunca recibe ningún respeto:

strcapture("^(.+?):(.+$)", df$text, proto=list(text1="", text2=""))
#       text1      text2
#1  separate1  and: more
#2 another 20         42

Insertado de nuevo:

cbind(df, strcapture("^(.+?):(.+$)", df$text, proto=list(text1="", text2="")))
#                  text      text1      text2
#1 separate1: and: more  separate1  and: more
#2       another 20: 42 another 20         42
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.