#r #igraph
#r #igraph
Вопрос:
У меня есть список людей, и я хочу изучить характеристики их сетей совместной работы. Однако я хочу использовать все ребра их сетей, а не только ребра, которые напрямую связаны с ними. Например, предположим, что я смотрю на сеть Боба. Для проекта 1 Боб, Билл и Джейн работали вместе.
Если бы я заботился только о ребрах, связанных с Бобом, тогда мой список ребер был бы: Боб-Билл, Боб-Джейн. В сети будет 0 треугольников. Однако, если бы я посмотрел на все ребра для сети Боба, список ребер выглядел бы так: Боб-Билл, Боб-Джейн, Билл-Джейн. Сеть будет иметь 1 треугольник.
Единственный способ сделать это, который я могу придумать, — создать «сгруппированный» список ребер. Я просто не уверен, как с этим справиться.
Мои данные ребер выглядят следующим образом:
collab <- data.frame(vertex1 = c("Bob","Bill","Bob","Jane","Bill","Jane","Bob","Jane","Bob","Bill","Bob"
,"Jane","Bill","Jane","Bob","Jane","Jane","Jill","Jane","Susan","Susan"),
edgeID = c(1,1,1,1,1,1,2,2,1,1,1,1,1,1,2,2,3,3,3,3,3),
vertex2 = c("Bill","Bob","Jane","Bob","Jane","Jill","Jane","Bob","Bill","Bob"
,"Jane","Bob","Jane","Bill","Jane","Bob","Jill","Jane","Susan","Jane","Jill"))
vertex1 edgeID vertex2
1 Bob 1 Bill
2 Bill 1 Bob
3 Bob 1 Jane
4 Jane 1 Bob
5 Bill 1 Jane
6 Jane 1 Jill
7 Bob 2 Jane
8 Jane 2 Bob
9 Jane 3 Jill
10 Jill 3 Jane
11 Jane 3 Susan
12 Susan 3 Jane
13 Susan 3 Jill
У меня есть другой вектор, который содержит имена моих целевых пользователей:
targets <- data.frame(name=c("Bob","Jane"))
Что я хотел бы сделать, так это сгруппировать соответствующие ребра под соответствующими целями, чтобы результат был примерно таким:
group vertex1 edgeID vertex2
1 Bob Bob 1 Bill
2 Bob Bill 1 Bob
3 Bob Bob 1 Jane
4 Bob Jane 1 Bob
5 Bob Bill 1 Jane
6 Bob Jane 1 Jill
7 Bob Bob 2 Jane
8 Bob Jane 2 Bob
9 Jane Bob 1 Bill
10 Jane Bill 1 Bob
11 Jane Bob 1 Jane
12 Jane Jane 1 Bob
13 Jane Bill 1 Jane
14 Jane Jane 1 Bill
15 Jane Bob 2 Jane
16 Jane Jane 2 Bob
17 Jane Jane 3 Jill
18 Jane Jill 3 Jane
19 Jane Jane 3 Susan
20 Jane Susan 3 Jane
21 Jane Susan 3 Jill
Я полагаю, что если я смогу добраться сюда, я смогу создать цикл for, который перебирает каждую цель, создает график с помощью iGraph и вычисляет сетевые показатели для Боба и Джейн без особых проблем. Правильно ли я поступаю или у iGraph есть лучший способ сделать это?
Ответ №1:
Здесь может быть один из вариантов
g <- graph_from_data_frame(collab[c(1, 3, 2)], directed = FALSE)
do.call(
rbind,
c(
make.row.names = FALSE,
lapply(
targets$name,
function(nm) {
z <- c(nm, V(g)$name[distances(g, nm) == 1])
cbind(group = nm, unique(subset(collab, vertex1 %in% z amp; vertex2 %in% z)))
}
)
)
)
что дает
group vertex1 edgeID vertex2
1 Bob Bob 1 Bill
2 Bob Bill 1 Bob
3 Bob Bob 1 Jane
4 Bob Jane 1 Bob
5 Bob Bill 1 Jane
6 Bob Bob 2 Jane
7 Bob Jane 2 Bob
8 Bob Jane 1 Bill
9 Jane Bob 1 Bill
10 Jane Bill 1 Bob
11 Jane Bob 1 Jane
12 Jane Jane 1 Bob
13 Jane Bill 1 Jane
14 Jane Jane 1 Jill
15 Jane Bob 2 Jane
16 Jane Jane 2 Bob
17 Jane Jane 1 Bill
18 Jane Jane 3 Jill
19 Jane Jill 3 Jane
20 Jane Jane 3 Susan
21 Jane Susan 3 Jane
22 Jane Susan 3 Jill
Комментарии:
1. Это отлично работает с образцами данных, которые я предоставил, но когда я пробую это на своих реальных данных, я получаю следующую ошибку: «Ошибка в расстояниях (g, nm): на итераторах.c: 759: невозможно создать итератор, неверный идентификатор вершины, неверный идентификатор вершины» Есть идеи, что это можетбыть?
2. Понял это. В моих фактических данных столбец targets$name является числовым. Передача числа в функцию distances() приводит к тому, что она обрабатывает число как индекс, что приводит к недопустимому идентификатору вершины. Вместо этого я передаю «как.character(targets$name)», чтобы заставить его учитывать имя вершины, а не рассматривать его как номер индекса.