r data.table melt

Convierta la representación numérica de la columna ''variable'' en una cadena original después de la fusión utilizando patrones



data.table melt (1)

Estoy usando el argumento patterns() en data.table::melt() para derretir datos que tienen columnas que tienen varios patrones fácilmente definidos. Está funcionando, pero no veo cómo puedo crear una variable de índice de caracteres en lugar del desglose numérico predeterminado.

Por ejemplo, en A las columnas de perros y gatos están numeradas ... eche un vistazo a la columna "variable":

A = data.table(idcol = c(1:5), dog_1 = c(1:5), cat_1 = c(101:105), dog_2 = c(6:10), cat_2 = c(106:110), dog_3 = c(11:15), cat_3 = c(111:115)) head(melt(A, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat"))) idcol variable dog cat 1: 1 1 1 101 2: 2 1 2 102 3: 3 1 3 103 4: 4 1 4 104 5: 5 1 5 105 6: 1 2 6 106

Sin embargo, en B las columnas perro y gato están numeradas con texto, pero la columna "variable" sigue siendo numérica.

B = data.table(idcol = c(1:5), dog_one = c(1:5), cat_one = c(101:105), dog_two = c(6:10), cat_two = c(106:110), dog_three = c(11:15), cat_three = c(111:115)) head(melt(B, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat"))) idcol variable dog cat 1: 1 1 1 101 2: 2 1 2 102 3: 3 1 3 103 4: 4 1 4 104 5: 5 1 5 105 6: 1 2 6 106

¿Cómo puedo llenar la columna "variable" con uno / dos / tres en lugar de 1/2/3?


Puede haber formas más fáciles, pero esto parece funcionar:

# grab suffixes of ''variable'' names suff <- unique(sub(''^.*_'', '''', names(B[ , -1]))) # suff <- unique(tstrsplit(names(B[, -1]), "_")[[2]]) # melt B2 <- melt(B, measure = patterns("^dog", "^cat"), value.name = c("dog", "cat")) # replace factor levels in ''variable'' with the suffixes setattr(B2$variable, "levels", suff) B2 # idcol variable dog cat # 1: 1 one 1 101 # 2: 2 one 2 102 # 3: 3 one 3 103 # 4: 4 one 4 104 # 5: 5 one 5 105 # 6: 1 two 6 106 # 7: 2 two 7 107 # 8: 3 two 8 108 # 9: 4 two 9 109 # 10: 5 two 10 110 # 11: 1 three 11 111 # 12: 2 three 12 112 # 13: 3 three 13 113 # 14: 4 three 14 114 # 15: 5 three 15 115

Tenga en cuenta que hay un problema abierto sobre este tema con algunas otras alternativas: FR: expansión de la funcionalidad de fusión para manejar nombres de salida .

Este es uno de los casos (raros) donde creo que good''ol base::reshape es más limpio. Su argumento sep es útil aquí: tanto los nombres de la columna ''valor'' como los niveles de las columnas ''variables'' se generan de una vez:

reshape(data = B, varying = names(B[ , -1]), sep = "_", direction = "long")