2012-04-11 10 views
10

Próbuję wyczyścić niektóre niepoprawnie wprowadzone dane. Pytanie do zmiennej pozwala na wielokrotne odpowiedzi z pięciu wyborów, ponumerowanych jako 1 do 5. Dane zostały wprowadzone w następujący sposób (jest to tylko przykład - w danych jest o wiele więcej zmiennych i więcej obserwacji) ramka):Rozdziel kolumnę połączonych danych rozdzielanych przecinkami i przekoduj dane wyjściowe jako czynniki

data 
      V1 
1 1, 2, 3 
2 1, 2, 4 
3 2, 3, 4, 5 
4 1, 3, 4 
5 1, 3, 5 
6 2, 3, 4, 5 

Oto niektóre kodu do odtworzenia tego przykładu dane:

data = data.frame(V1 = c("1, 2, 3", "1, 2, 4", "2, 3, 4, 5", 
         "1, 3, 4", "1, 3, 5", "2, 3, 4, 5")) 

Co tak naprawdę potrzebne jest dane mają być traktowani ... binary - jak zestaw „tak/brak "pytań" wprowadzonych w ramce danych, która wygląda bardziej jak:

data 
    V1.1 V1.2 V1.3 V1.4 V1.5 
1  1  1  1 NA NA 
2  1  1 NA  1 NA 
3  NA  1  1  1  1 
4  1 NA  1  1 NA 
5  1 NA  1 NA  1 
6  NA  1  1  1  1 

Rzeczywiste nazwy zmiennych nie mają w tej chwili znaczenia - mogę to łatwo naprawić. Poza tym nie ma znaczenia, czy brakujące elementy to "O", "NA", czy puste - znowu, to coś, co mogę naprawić później.

Próbowałem używać funkcji transform z pakietu reshape, a także karmić różne rzeczy z strsplit, ale nie mogę dostać, aby zrobić to, czego szukam. Spojrzałem również na wiele innych powiązanych pytań na temat Stackoverflow, ale nie wydają się być całkiem ten sam problem.

Odpowiedz

8

Trzeba tylko napisać funkcję i użyć apply. Po pierwsze niektóre atrapa dane:

##Make sure you're not using factors 
dd = data.frame(V1 = c("1, 2, 3", "1, 2, 4", "2, 3, 4, 5", 
         "1, 3, 4", "1, 3, 5", "2, 3, 4, 5"), 
        stringsAsFactors=FALSE) 

Następnie należy utworzyć funkcję, która pobiera z rzędu i przekształca w razie potrzeby

make_row = function(i, ncol=5) { 
    ##Could make the default NA if needed 
    m = numeric(ncol) 
    v = as.numeric(strsplit(i, ",")[[1]]) 
    m[v] = 1 
    return(m) 
} 

Następnie użyj apply i transpozycji wynikiem

t(apply(dd, 1, make_row)) 
+0

Oto jedna wkładka automatycznie określić odpowiednią wartość dla zmiennej '' ncol' V1': 'max (as.numeric (nie wyświetlać na liście (strsplit (dd $ V1, ""))))' (zakładając, że ostatnia z wielu odpowiedzi została podana jako odpowiedź przynajmniej raz) – BenBarnes

6

dawno później, w końcu udało mi się stworzyć pakiet ("splitstackshape"), który zajmuje się tego rodzaju danymi w efektywny sposób. Tak więc, dla wygody innych osób (i pewnej autopromocji, oczywiście) jest to kompaktowe rozwiązanie.

Istotną funkcją tego problemu jest cSplit_e.

pierwsze, ustawienia domyślne, która zachowuje oryginalną kolumnę i wykorzystuje NA jako wypełnienia:

library(splitstackshape) 
cSplit_e(data, "V1") 
#   V1 V1_1 V1_2 V1_3 V1_4 V1_5 
# 1 1, 2, 3 1 1 1 NA NA 
# 2 1, 2, 4 1 1 NA 1 NA 
# 3 2, 3, 4, 5 NA 1 1 1 1 
# 4 1, 3, 4 1 NA 1 1 NA 
# 5 1, 3, 5 1 NA 1 NA 1 
# 6 2, 3, 4, 5 NA 1 1 1 1 

drugie, spada oryginalną kolumnę i korzystania 0 jako wypełnienia.

cSplit_e(data, "V1", drop = TRUE, fill = 0) 
# V1_1 V1_2 V1_3 V1_4 V1_5 
# 1 1 1 1 0 0 
# 2 1 1 0 1 0 
# 3 0 1 1 1 1 
# 4 1 0 1 1 0 
# 5 1 0 1 0 1 
# 6 0 1 1 1 1 
Powiązane problemy