Mam tabelę danych .
groups <- data.table(group = c("A", "B", "C", "D", "E", "F", "G"),
code_1 = c(2,2,2,7,8,NA,5),
code_2 = c(NA,3,NA,3,NA,NA,2),
code_3 = c(4,1,1,4,4,1,8))
group code_1 code_2 code_3
A 2 NA 4
B 2 3 1
C 2 NA 1
D 7 3 4
E 8 NA 4
F NA NA 1
G 5 2 8
Chciałbym, aby każda grupa znalazła najbliższych sąsiadów na podstawie dostępnych kodów. Na przykład: Grupa A ma bezpośrednie grupy sąsiadów B, C z powodu kodu_1 (kod_1 jest równy 2 we wszystkich grupach) i ma bezpośrednie grupy sąsiadów D, E z powodu kodu_3 (kod_3 jest równy 4 we wszystkich tych grupach).
Próbowałem dla każdego kodu, podzestawiając pierwszą kolumnę (grupę) na podstawie dopasowań w następujący sposób:
groups$code_1_match = list()
for (row in 1:nrow(groups)){
set(groups, i=row, j="code_1_match", list(groups$group[groups$code_1[row] == groups$code_1]))
}
group code_1 code_2 code_3 code_1_match
A 2 NA 4 A,B,C,NA
B 2 3 1 A,B,C,NA
C 2 NA 1 A,B,C,NA
D 7 3 4 D,NA
E 8 NA 4 E,NA
F NA NA 1 NA,NA,NA,NA,NA,NA,...
G 5 2 8 NA,G
To „trochę” działa, ale przypuszczam, że istnieje więcej sposobów na zrobienie tego. próbowałem
groups[, code_1_match_2 := list(group[code_1 == groups$code_1])]
Ale to nie działa.
Czy brakuje mi oczywistej sztuczki z tabelą danych, aby sobie z tym poradzić?
Mój idealny przypadek wyglądałby tak (co obecnie wymagałoby użycia mojej metody dla wszystkich 3 kolumn, a następnie połączenia wyników):
group code_1 code_2 code_3 Immediate neighbors
A 2 NA 4 B,C,D,E
B 2 3 1 A,C,D,F
C 2 NA 1 A,B,F
D 7 3 4 B,A
E 8 NA 4 A,D
F NA NA 1 B,C
G 5 2 8
źródło
igraph
, które może być naprawdę interesujące.Odpowiedzi:
Za pomocą igraph uzyskaj sąsiadów 2 stopnia, upuść węzły numeryczne, wklej pozostałe węzły.
Więcej informacji
Tak wyglądają nasze dane przed konwersją na obiekt igraph. Chcemy upewnić się, że kod1 o wartości 2 różni się od kodu2 o wartości 2 itd.
Oto jak wygląda nasza sieć:
Pamiętaj, że
A..G
węzły są zawsze połączonecode_x_y
. Musimy więc uzyskać stopień 2, dajemyego(..., order = 2)
sąsiadom do 2 stopnia, i zwraca obiekt listy.Aby uzyskać nazwy:
Aby udoskonalić wynik, musimy usunąć
code_x_y
węzły i węzeł źródłowy (1. węzeł)źródło
Nie ma chyba trochę bardziej praktycznym sposobem osiągnięcia tego celu, ale mógłby zrobić coś takiego, za pomocą topi się i dołącza:
źródło
Jest to inspirowane stopniem @ sindri_baldur. To rozwiązanie:
źródło
Jak wspomniano w zx8754, używanie
data.table::melt
z,combn
a następnieigraph::as_adjacency_matrix
wynik:
lub bez użycia
igraph
wynik:
źródło
xtabs
stworzyć podobny wynik jakigraph
krok?table
lubxtabs