2017-01-26 21 views
6

Używam argumentu patterns() w data.table::melt() do topienia danych, które mają kolumny z kilkoma łatwo zdefiniowanymi wzorcami. Działa, ale nie widzę, jak mogę utworzyć zmienną indeksu znaków zamiast domyślnego podziału na liczby.Konwersja reprezentacji numerycznej kolumny "zmienna" na oryginalny ciąg po topieniu za pomocą wzorców

Na przykład w kolumny psów i kotów są policzone ... przyjrzeć się na „zmienny” kolumny:

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 

Jednak w B kolumny psów i kotów są ponumerowane z tekstem , ale kolumna "zmienna" jest nadal numeryczna.

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 

Jak mogę wypełnić kolumnę "zmienną" za pomocą jednego/dwóch/trzech zamiast 1/2/3?

Odpowiedz

7

Nie może być prostsze sposoby, ale to wydaje się działać:

# 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 

pamiętać, że kwestią otwartą na ten temat z kilkoma innymi alternatywami: FR: expansion of melt functionality for handling names of output.


Jest to jeden z (rzadkie) przypadki, w których wierzę good'ol base::reshape jest czystsze. Jego sep argumentem jest przydatna tutaj - obie nazwy w kolumnie „wartość”, a poziomy kolumnach „zmienna” są generowane w jednej porcji:

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

tak, zmienna col. poziomy muszą być skonstruowane ręcznie jeszcze .. Kciuki w górze dla bazy :: zmiana kształtu. – Arun

+0

Link do problemu z Githubem jest bardzo pomocny! – Nancy