2012-03-15 12 views
17

Mam element data.frame i próbuję utworzyć tabelę częstotliwości, która pokazuje częstotliwość wartości dla każdego wiersza. Więc zaczynam się coś takiego:Konwertuj ramkę danych na specjalnie sformatowaną tabelę częstotliwości.

d <- data.frame(a=c(1,2,3), b=c(3,4,5), c=c(1,2,5)) 

który wygląda tak:

a b c 
    1 3 1 
    2 4 2 
    3 5 5 

Co naprawdę chciałbym stworzyć to data.frame awaryjny lub matryca, która wygląda tak:

1, 2, 3, 4, 5, 6, 7, 8, 9 
2, 0, 1, 0, 0, 0, 0, 0, 0 
0, 2, 0, 1, 0, 0, 0, 0, 0 
0, 0, 1, 0, 2, 0, 0, 0, 0 

Górny rząd jest po prostu rzędem etykiet i nie musi być w końcowym wyniku. Ale dodałem go tam w celach ilustracyjnych. W każdym wierszu wyświetlane są cyfry 1: 9 oraz liczba wyświetleń każdej cyfry w każdym wierszu danych początkowych.

Nie mogę owinąć głowy w łatwy sposób, aby to zrobić. Chociaż wygląda na to, że funkcja table() powinna być pomocna, nie mogę jej zmusić do miłości. Każda pomoc lub pomysły są doceniane.

+4

Masz data.frame pełną liczb? Jak szybko zapomnisz, konik polny ... użyj matrycy. –

+0

Czy użycie matrycy zmienia odpowiedź? –

+0

To nie zmienia odpowiedzi Josha O'Briena, ponieważ 'apply' automatycznie przekształca pierwszy argument w macierz/tablicę. Nie jestem pewien co do Ilyi. I tak w większości się drażniłem. ;-) –

Odpowiedz

11

Proszę bardzo:

t(apply(d, 1, tabulate, nbin=9)) 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 2 0 1 0 0 0 0 0 0 
[2,] 0 2 0 1 0 0 0 0 0 
[3,] 0 0 1 0 2 0 0 0 0 

(Choć to chyba nie ma znaczenia w niniejszym wniosku, tabulate() (który jest używany wewnątrz kodu dla table()) jest również miły dla imponującej szybkości, z jaką wykonuje jej obliczenia)


EDIT. tabulate() nie jest skonfigurowany do czynienia z 0s lub ujemnych liczb całkowitych. Jeśli chcesz inny jeden liner, który robi, można użyć table() jednak robi coś takiego:

d <- data.frame(a=c(0,-1,-2), b=c(3,4,5), c=c(1,2,5)) 

t(apply(d, 1, function(X) table(c(X, -9:9)) - 1)) 
    -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 
[1,] 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 
[2,] 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 
[3,] 0 0 0 0 0 0 0 1 0 0 0 0 0 0 2 0 0 0 0 
+0

Zdecydowanie (inny) jeden z tych prostych klejnotów bazy R. Jeszcze raz dziękuję R-core! –

+0

jakikolwiek sposób, aby go pomieścić zero i wartości ujemne? Po sprawdzeniu mojego przypadku użycia, są one ważniejsze niż zdałem sobie sprawę, kiedy zrobiłem proste pytanie. –

+1

@JDLong - Dodałem jednolinijkę używając 'table()', która radzi sobie z grą z zerowymi i ujemnymi liczbami całkowitymi. Wystarczy dopasować bit '-9: 9', aby objąć dowolny zakres, a wszystkie liczby spoza tego zakresu będą nadal zawarte w tabeli. Dodając kilka wstępnych linii, które sprawdzają zakres liczb całkowitych w oryginalnym pliku data.frame i ustawiasz zakres w tabeli wyjściowej, możesz łatwo zawinąć to w małą, małą funkcję, aby zrobić to, co chcesz. Twoje zdrowie. –

8

innego rozwiązania z wykorzystaniem tabeli

library(reshape) 
d <- data.frame(a=c(1,2,3), b=c(3,4,5), c=c(1,2,5)) 
d2 <- melt(d) 
d2$rows <- rep(1:nrow(d), ncol(d)) 
table(d2$rows, d2$value) 
+0

ma to wyraźną zaletę, że poprawnie radzi sobie z zerami i wartościami ujemnymi, co było moim następstwem. Bardzo dobrze! –

Powiązane problemy