2017-10-04 11 views
5

Mam problem z moim data.frame macierzy kwadratowej. Teraz moje dane wygląda mniej więcej tak:Tworzenie macierzy kwadratowej z ramki danych

var1 var2 value 
    A B  4 
    C D  5 
    D A  2 
    B D  1 

Próbuję przekształcić data.frame do matrycy, która wygląda tak:

A B C D 
    A 0 4 0 2 
    B 4 0 0 1 
    C 0 0 0 5 
    D 2 1 5 0 

Próbowałem wiele funkcji z innego pakietu dostępnego w R, ale nadal nie może znaleźć rozwiązania.

+0

proszę pisać te wiele funkcji, które zostały wypróbowane i dlaczego to nie działa – PoGibas

+1

'xtabs (wartość ~ var1 + var2, df)'? – Sotos

+1

@Sotos to pominie kolumnę 'C' – PoGibas

Odpowiedz

3

Jeśli wykonamy wszystkie kolumny znaków factor s z poziomami "A", "B", "C", "D", możemy użyć xtabs bez upuszczania kolumn.

Niestety wynikowa macierz nie jest symetryczna.

library('tidyverse') 

df <- tribble(
    ~var1, ~var2, ~value, 
    'A', 'B',  4, 
    'C', 'D',  5, 
    'D', 'A',  2, 
    'B', 'D',  1 
) 

df %>% 
    mutate_if(is.character, factor, levels=c('A', 'B', 'C', 'D')) %>% 
    xtabs(value ~ var1 + var2, ., drop.unused.levels = F) 
#  var2 
# var1 A B C D 
# A 0 4 0 0 
# B 0 0 0 1 
# C 0 0 0 5 
# D 2 0 0 0 

Po to, aby był symetryczny, właśnie dodałem do niego transpozycję. To jednak wydaje się trochę hackować.

df %>% 
    mutate_if(is.character, factor, levels=c('A', 'B', 'C', 'D')) %>% 
    xtabs(value ~ var1 + var2, ., drop.unused.levels = F) %>% 
    '+'(., t(.)) 
#  var2 
# var1 A B C D 
# A 0 4 0 2 
# B 4 0 0 1 
# C 0 0 0 5 
# D 2 1 5 0 
+0

" To wygląda jak trochę hackowania, chociaż "- coś, co można powiedzieć o wielu dobrych rozwiązaniach w R. +1 –

+0

Dziękuję za szczegółową odpowiedź @Paul. Ale tak naprawdę nadal mam problem, ponieważ przechowuję zmienne w ramce danych. 'df <- tribble (~ var1, ~ var2, ~ score, dane3 $ var1, dane3 $ var2, dane3 $ score) df%>% mutate_if (is.character, factor, levels = c ('data3 $ var1' , "data3 $ var2"))%>% xtabs (score ~ ​​var1 + var2,., drop.unused.levels = F)%>% '+' (., t (.)) ' – Brenna

+0

Sposób, w jaki używasz 'tribble' spowoduje wyświetlanie kolumn-list. Możesz po prostu użyć 'data3%>% mutate_if (is.znak, współczynnik, poziomy = c ("A", "B", "C", "D"))%>% xtabs (score ~ ​​var1 + var2,., drop.unused.levels = F)%>% ' + '(., t (.)) ' – Paul

3

Oto podstawowa metoda R z wykorzystaniem indeksowania macierzy w wektorach znakowych.

## set up matrix 
# get names for row and columns 
nameVals <- sort(unique(unlist(dat[1:2]))) 
# construct 0 matrix of correct dimensions with row and column names 
myMat <- matrix(0, length(nameVals), length(nameVals), dimnames = list(nameVals, nameVals)) 

# fill in the matrix with matrix indexing on row and column names 
myMat[as.matrix(dat[c("var1", "var2")])] <- dat[["value"]] 

ta zwraca

myMat 
    A B C D 
A 0 4 0 0 
B 0 0 0 1 
C 0 0 0 5 
D 2 0 0 0 

Szczegółowe informacje o tym, jak działa indeksowanie, patrz sekcji pliku pomocy ?"["matryce i tablic. Czwarty akapit omawia tę formę indeksowania.

Należy zauważyć, że zakładam, że dwie pierwsze zmienne to wektory znakowe, a nie czynniki. To sprawia, że ​​jest to trochę łatwiejsze, ponieważ nie muszę używać as.character, aby je przymusić.

Aby przekonwertować wynik na data.frame, wystarczy zawinąć go w as.data.frame.

dane

dat <- 
structure(list(var1 = c("A", "C", "D", "B"), var2 = c("B", "D", 
"A", "D"), value = c(4L, 5L, 2L, 1L)), .Names = c("var1", "var2", 
"value"), class = "data.frame", row.names = c(NA, -4L)) 
Powiązane problemy