Supongamos que tengo datos que tienen el siguiente formato:

ID VALUE
a  a
a  b
d  b
d  c

Lo que me gustaría hacer es una codificación en caliente para el valor de ID. Cuando uso model.matrix, obtengo:

model.matrix(~VALUE-1, df)

ID aVALUE bVALUE cVALUE
a  1      0      0
a  0      1      0
d  0      1      0
d  0      0      1

Sin embargo, lo que me gustaría obtener es esto:

ID aVALUE bVALUE cVALUE
a  1      1      0
d  0      1      1

La otra parte de esto es que mi marco de datos tiene aproximadamente 30 millones de filas, por lo que estoy buscando una forma eficiente de hacer esto. ¡Cualquier ayuda o comentario será muy apreciado!

¡Gracias!

1
RDizzl3 31 jul. 2016 a las 04:13

2 respuestas

La mejor respuesta

Podría usar table.

d <- table(df$ID, df$VALUE)
#    a b c
#  a 1 2 0
#  d 0 1 1

Si tiene que aplicar valores de 1 o 0 porque algunas combinaciones aparecen más de una vez, puede convertir esos casos en 1:

d[d > 1L] <- 1
#    a b c
#  a 1 1 0
#  d 0 1 1

Datos de ejemplo

df <- structure(list(ID = c("a", "a", "a", "d", "d"), VALUE = c("a", "b", "b", "b", "c")),
   .Names = c("ID", "VALUE"), class = "data.frame", row.names = c(NA, -5L))
4
Jota 31 jul. 2016 a las 02:18

Una opción es dcast de data.table para convertir a formato 'ancho' de 'largo'. Convierta el 'data.frame' a 'data.table' (setDT(df)), modifíquelo a formato 'ancho' con dcast y especifique fun.aggregate. Para grandes conjuntos de datos, el enfoque dcast sería rápido.

library(data.table)
dcast(setDT(df), ID~paste0(VALUE, "VALUE"), value.var = "VALUE", 
                function(x) as.integer(length(x) > 0))
#    ID aVALUE bVALUE cVALUE
#1:  a      1      1      0
#2:  d      0      1      1

Otra opción es dplyr/tidyr

library(dplyr)
library(tidyr)
df %>% 
   unique() %>%
   mutate(n = 1)%>% 
   spread(VALUE, n, fill = 0)
2
akrun 31 jul. 2016 a las 03:58