Saltar al contenido

Recodificar una lista separada por punto y coma en R

Israel, parte de nuestro equipo, nos ha hecho el favor de redactar este artículo ya que conoce muy bien el tema.

Solución:

Con un data.table solución, puedes usar tstrsplit:

library(data.table)

df <- data.table::data.table(
  color = c("red;blue", "red;green")
)

df[, c("col1","col2") := tstrsplit(color, ";", fixed = TRUE)] 
df[, "green" := (col2 == "green")]

df

#       color col1  col2 green
# 1:  red;blue  red  blue FALSE
# 2: red;green  red green  TRUE

Si no está familiarizado con data.table operador de actualización por referencia :=, data.table las viñetas son un buen punto de partida. La opción fixed = TRUE en tstrsplit asume que siempre tiene el mismo número de elementos en su lista separada por comas.

Hay una solución que, creo, se adapta más a una situación en la que tienes más de unos pocos valores. Usando repetidamente lapply, puede agregar una serie de columnas a su data.table

Empezando de nuevo con df:

df <- data.table::data.table(
  color = c("red;blue", "red;green")
)

Vocación lapply con grepl para buscar el color relevante, actualizamos por referencia nuestro objeto (tenga en cuenta que puede usar más de tres colores):

lapply(c("red","green","blue"), function(x)
  df[grepl(x, color), c(as.character(x)) := TRUE]
)
#[[1]]

#[[2]]
#       color  red green blue
#1:  red;blue TRUE    NA TRUE
#2: red;green TRUE  TRUE   NA

#[[3]]
#       color  red green blue
#1:  red;blue TRUE    NA TRUE
#2: red;green TRUE  TRUE   NA

No es necesario reasignar el marco de datos. Ha sido actualizado por referencia. Solo la última ranura de df nos interesa. Finalmente, seleccionando este y configurando NAs a FALSE:

df <- df[[length(df)]]
df[is.na(df)] <- FALSE

df
#       color  red green  blue
# 1:  red;blue TRUE FALSE  TRUE
# 2: red;green TRUE  TRUE FALSE

Espero eso ayude

Nosotros podemos usar str_detect

library(dplyr)
library(stringr)
df %>% 
      mutate(green = +(str_detect(colors, 'green')))

Actualizar

Si quisiéramos nuevas columnas

library(qdapTools)
cbind(df, mtabulate(strsplit(df$colors, ";")))
#     colors blue green red
#1  red;blue    1     0   1
#2 red;green    0     1   1

O usando base R

cbind(df, as.data.frame.matrix(table(stack(setNames(strsplit(df$colors, ";"), 
                 seq_along(df$colors)))[2:1])))

En el código de OP, el strsplitlist primer elemento[[1]]) se selecciona en lugar de recorrer la lista, lo que resulta en el reciclaje del elemento y obtiene FALSE ya que no hay 'verde' en el primer list elemento

library(purrr)
df %>%
   mutate(green = map_int(strsplit(colors, ";"), 
               ~ case_when('green' %in% .x ~ 1L, TRUE ~ 0L)))
#     colors green
#1  red;blue     0
#2 red;green     1

Datos

colors <- c("red;blue", "red;green")
df <- data.frame(colors, stringsAsFactors = FALSE)

Código

cbind.data.frame(colors,
                 sapply( unique(unlist(strsplit( unlist(df), ";", fixed = TRUE))), 
                         function(x) as.integer(grepl(x, colors))))

Producción

#      colors red blue green
# 1  red;blue   1    1     0
# 2 red;green   1    0     1

Utilizando %in% y sin expresión regular en un conjunto de datos diferente con elementos similares: verde y verdoso

colors <- c("red;blue;greenish", "red;green")
df <- data.frame(colors, stringsAsFactors = FALSE)

myfun <- function(x)  unique(unlist(strsplit( unlist(x), ";", fixed = TRUE))) 
df2 <- t(sapply( df$colors, function(x)  as.integer(myfun(df) %in% myfun(x))))
colnames(df2) <- myfun(df)
df2
#                   red blue greenish green
# red;blue;greenish   1    1        1     0
# red;green           1    0        0     1

Reseñas y calificaciones del tutorial

Recuerda mostrar este artículo si lograste el éxito.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *