Получение значений смежности в объекте nng igraph в R

отредактировано для повышения качества вопроса в результате (вполне уместной) порки, полученной Spacedman!

У меня есть объект k-ближайших соседей (igraph), который я создал как таковой, используя загруженный мной файл здесь:

Я выполнил следующие операции с данными, чтобы создать матрицу смежности расстояний между наблюдениями:

W <- read.csv("/path/sim_matrix.csv")
W <- W[, -c(1,3)]
W <- scale(W)

sim_matrix <- dist(W, method = "euclidean", upper=TRUE)
sim_matrix  <- as.matrix(sim_matrix)

mygraph <- nng(sim_matrix, k=10)  

Это дает мне хороший список вершин и их десять ближайших соседей, небольшой пример следует ниже:

  1 ->  25  26  28  30  32 144 146 151 177 183     2 ->   4   8  32  33 145 146 154 156 186 199
  3 ->   1  25  28  51  54 106 144 151 177 234     4 ->   7   8  89  95  97 158 160 170 186 204
  5 ->   9  11  17  19  21 112 119 138 145 158     6 ->  10  12  14  18  20  22 147 148 157 194
  7 ->   4  13 123 132 135 142 160 170 173 174     8 ->   4   7  89  90  95  97 158 160 186 204  

Все идет нормально.

Однако я борюсь с тем, как получить доступ к значениям весов между вершинами, с которыми я могу выполнять значимые вычисления. Не должно быть так сложно, это обычное дело для графиков, не так ли?

Посмотрев документацию, я попробовал:

degree(mygraph)  

что дает мне сумму весов для каждого узла. Но мне не нужна сумма, мне нужны необработанные данные, чтобы я мог делать свои собственные вычисления.

Я пытался

get.data.frame(mygraph,"E")[1:10,]  

но здесь нет расстояний между узлами:

   from  to
1     1  25
2     1  26
3     1  28
4     1  30
5     1  32
6     1 144
7     1 146
8     1 151
9     1 177
10    1 183

Я попытался получить значения весов между вершинами вне графического объекта, с которыми я могу работать, но безуспешно.

Если у кого-то есть идеи, как подойти к этому, я был бы признателен. Спасибо.


person tumultous_rooster    schedule 11.05.2014    source источник
comment
Что за функция nng? Ваш вопрос невозможно воспроизвести как есть.   -  person Spacedman    schedule 11.05.2014
comment
Пожалуйста, сделайте игрушечный пример с небольшой матрицей расстояний, по которому мы все сможем пробежать. Дайте весь код. Мой ответ - не то, что вы хотели, потому что вам было непонятно. Я думаю, вам, вероятно, просто нужно найти sim_matrix[i,j] для каждого из from, to, чтобы считать расстояние, если sim_matrix - это матрица расстояний NxN .... в противном случае, если это матрица данных Nxm, тогда найдите данные и выполните пифагор.   -  person Spacedman    schedule 11.05.2014
comment
@Spacedman: я обновил вопрос и добавил ссылку на матрицу смежности, которую я использую (в форме csv).   -  person tumultous_rooster    schedule 12.05.2014
comment
Теперь покажите нам код, который считывает CSV и создает sim_matrix. Просто read.csv дает мне матрицу 252x253 .. чего? Расстояния? С дополнительной колонкой в ​​начале. Хорошо, мне нужно вычистить это ... Почему я это делаю? Вы должны просто вставить две или три строки, которые ВЫ уже разработали, чтобы нам не пришлось.   -  person Spacedman    schedule 12.05.2014
comment
Является ли файл, о котором вы нам ничего не рассказали, матрицей РАССТОЯНИЙ или матрицей ПЕРЕМЕННЫХ, в которой расстояние вычисляется между строками? Тот факт, что он квадратный, заставляет меня думать о первом, но это означает, что вы должны использовать dx=sim_matrix в своем nng вызове. Это имеет огромное значение для получения возможных расстояний, поскольку в первом случае это просто поиск, а во втором - расстояния Пифагора (или манхэттена, или махаланобиса).   -  person Spacedman    schedule 12.05.2014
comment
Spacedman: вопрос отредактирован соответствующим образом. Я знаю, что выхожу из числа тех людей, которые принижают ценность SO, написав неполные вопросы, и я прошу прощения.   -  person tumultous_rooster    schedule 13.05.2014
comment
Закрывать! Я не могу сопоставить тот список смежности, который вы распечатали как небольшой образец. Так что я только что потратил десять минут, пытаясь понять, моя это вина или твоя. Думаю, это твое! get.adjlist(mygraph)[[1]] очень немного отличается, так что вы либо предоставили нам другие данные, либо допустили опечатку. Я знаю, что это мелочь, но здесь так важна точность. Также я думаю, что теперь ясно, что sim_matrix - это матрица расстояний, поэтому вам нужно сделать dx=sim_matrix или x=W, иначе ваш график - неправильный вариант для начала. Сначала получите код, работающий с крошечными вручную доказываемыми примерами.   -  person Spacedman    schedule 13.05.2014


Ответы (2)


Из вашего вопроса неясно, начинаете ли вы с набора данных или с матрицы расстояний, например. nng(x=mydata,...) или nng(dx=mydistancematrix,...), так что вот решения для обоих.

library(cccd)

df <- mtcars[,c("mpg","hp")]    # extract from mtcars dataset
# knn using dataset only
g  <- nng(x=as.matrix(df),k=5)  # for each car, 5 other most similar mpg and hp
V(g)$name <- rownames(df)       # meaningful names for the vertices
dm <- as.matrix(dist(df))       # full distance matrix
E(g)$weight <- apply(get.edges(g,1:ecount(g)),1,function(x)dm[x[1],x[2]])

# knn using distance matrix (assumes you have dm already)
h <- nng(dx=dm,k=5)
V(h)$name <- rownames(df)
E(h)$weight <- apply(get.edges(h,1:ecount(h)),1,function(x)dm[x[1],x[2]])

# same result either way
identical(get.data.frame(g),get.data.frame(h))
# [1] TRUE

Таким образом, эти подходы определяют расстояния от каждой вершины до пяти ближайших соседей и устанавливают для атрибута edge weight эти значения. Интересно, что plot(g) работает нормально, но plot(h) не работает. Я думаю, это может быть ошибка в методе построения графика для cccd.

Если все, что вам нужно знать, это расстояния от каждой вершины до ближайших соседей, приведенный ниже код не требует пакета cccd.

knn <- t(apply(dm,1,function(x)sort(x)[2:6]))
rownames(knn) <- rownames(df)

Здесь матрица knn имеет строку для каждой вершины и столбцы, определяющие расстояние от этой вершины до 5 ближайших соседей. Однако он не сообщает вам, какие это соседи.

person jlhoward    schedule 11.05.2014

Хорошо, я нашел nng функцию в cccd пакете. Это оно? Если это так ... тогда mygraph - это просто объект igraph, и вы можете просто сделать E(mygraph)$whatever, чтобы получить имена атрибутов края.

Следуя одному из cccd примеров создания G1 здесь, вы можете получить фрейм данных всех ребер и атрибутов таким образом:

get.data.frame(G1,"E")[1:10,]

Вы можете получить / установить отдельные атрибуты ребер с помощью E(g)$whatever:

> E(G1)$weight=1:250
> E(G1)$whatever=runif(250)
> get.data.frame(G1,"E")[1:10,]
   from to weight   whatever
1     1  3      1 0.11861240
2     1  7      2 0.06935047
3     1 22      3 0.32040316
4     1 29      4 0.86991432
5     1 31      5 0.47728632

Это то, что вам нужно? Любой igraph учебник по пакету расскажет вам больше!

person Spacedman    schedule 11.05.2014