Схожу с ума с forceNetwork в R: ребра не отображаются

Я уже неделю пытаюсь построить сеть с помощью пакета networkD3 в R. Функция simpleNetwork работает нормально, но не позволяет сильно контролировать внешний вид графика. Для этой цели существует функция forceNetwork: отображать график с расширенными визуальными возможностями.

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

Вот мои data.frames:

край

Gene1 Gene2 Prob
  1    22    3
  2    22    6
  3    22    6
  4    22    9
  5    22    3
  6    22    4
  7    22    8
  8    22    4
  9    22    6
 10    22    8
 11    22    6
 12    22   10
 13    22    6
 14    22    3
 15    22    6
 16    22    6
 17    22    0
 18    22    4
 19    22    6
 20    22    4

верт

Symbol Chr Expr
   1   21    9
   2   17   10
   3   17    0
   4   20    0
   5    6    9
   6    5   11
   7   12    0
   8    1   20
   9   17   11
  10   17    7
  11   17   11
  12   10    0
  13   17    0
  14    7    7
  15   17    6
  16   17    0
  17    2    5
  18    5   10
  19   17   10
  20   17    9
  21   12    4
  22    3    2

Что ж, это приводит к вышеупомянутому облаку узлов без ребер. То же самое, если я изменю столбец «Символ» на фактические метки, которые я поместил на узлы (с учетом порядка таблицы ссылок, как того требует пакет).

Обратите внимание, что пакет иллюстрирует использование этой функции на этом примере, и если вы откроете используемые наборы данных (MisLinks, MisNodes), их содержимое такое же, как у меня, за исключением меток узлов. Запуск того же самого примера работает; работает с моими данными нет.

Вот функция, которую я использую для построения сети:

forceNetwork( Links = edg, Nodes = vert, Source = "Gene1", Target = "Gene2", 
              Value = "Prob", NodeID = "Symbol", Group = "Chr", opacity = 0.7,
              colourScale = "d3.scale.category20b()", Nodesize = "Expr", zoom = T,
              legend = T )

Все остальные свойства отображаются правильно (размер узла, легенда, цвета), но я не вижу границ. Где-то в моих наборах данных должна быть ошибка, которую я никак не могу найти.


person Faabiioo    schedule 02.07.2015    source источник
comment
Попробуйте forceNetwork( Links = transform(edg, Gene1 = Gene1-1, Gene2 = Gene2 - 1), Nodes = transform(vert, Symbol = Symbol -1), Source = "Gene1", Target = "Gene2", Value = "Prob", NodeID = "Symbol", Group = "Chr", opacity = 0.7, colourScale = "d3.scale.category20b()", Nodesize = "Expr", zoom = T, legend = T ), чтобы идентификаторы вершин начинались с 0 вместо 1.   -  person lukeA    schedule 03.07.2015
comment
Неа! ничего не меняется, края не отображаются. Я перестроил фреймы данных, назвал NodeIds 0:21 и ребра соответственно. Ничего не меняется. Пробовал также использовать метки вместо чисел в столбце «Символ»: по-прежнему отображаются только узлы. В конце концов попытался изменить имена столбцов на те, которые использовались в примере пакета (глупо, я знаю): по-прежнему только узлы.   -  person Faabiioo    schedule 03.07.2015
comment
Странный. Приведенный выше код дает imgur.com/73b0eiJ. Я использую networkD3 v0.1.7.   -  person lukeA    schedule 03.07.2015
comment
М-м-м. СТРАННЫЙ! в итоге получил тот же результат, что и у вас, с приведенным выше набором тестов. Затем я применил ту же технику (фактически перестроил фреймы данных, начиная с нумерации с 0) к более конкретному тестовому случаю со 160 узлами и 170 ребрами. новые наборы данных, где на самом деле полные таблицы с несколькими столбцами, и я просто указал источник, цель и NodeId (на этот раз полные метки). первые попытки привели к пустой панели просмотра. тогда я мог бы получить сюжет, который я ожидал. ничего не меняя. что стоит за этой функцией? большое спасибо @lukeA   -  person Faabiioo    schedule 03.07.2015
comment
Может баг? Не могу сказать, так как не могу воспроизвести вашу ошибку.   -  person lukeA    schedule 03.07.2015


Ответы (4)


У меня была та же проблема (simpleNetwork работал нормально, forceNetwork сначала отображались только узлы и без ребер, а затем вообще не отображались).

Проблема (которую вы, по-видимому, исправили, когда «перестраивали кадры данных, начиная с нумерации с 0»), заключалась в том, что ваши исходные данные Links, edg, начинались с 1 вместо 0?

В документации networkD3, http://christophergandrud.github.io/networkD3/, есть следующее примечание:

Примечание. Вы, вероятно, привыкли к нумерации R, основанной на 1 (т. е. счет в R начинается с 1). Однако графики networkD3 создаются с использованием JavaScript, который основан на 0. Таким образом, ваши ссылки на данные должны начинаться с 0.

Ре. неправильные типы данных, которые, как я изначально думал, могут быть проблемой, я протестировал приведение всех различных столбцов (кроме переменной фактора для NodeID) as.numeric против as.integer - однако теперь исправив мои данные, чтобы они основывались на 0, а не на 1, мой дисплей forceNetwork нормально работает с любым типом данных.

Надеюсь это поможет!

person CRT    schedule 28.02.2016

Я только что исправил ту же проблему в своей собственной сети forceNetwork. Оказалось, что фрейм данных ребер, который я создал (экспортировал из iGraph), имел character типов, а не int типов. Приведение столбцов "от" и "к" с использованием as.numeric() решило проблему, и ссылки отрисовывались правильно.

Надеюсь, это поможет.

С уважением,

Буду

person Will Hardman    schedule 11.01.2016

С технической точки зрения, причина, по которой данные вашего примера не будут работать, даже если вы решите другие возможные проблемы (например, edg$Gene1 и edg$Gene2 не являются числовыми), заключается в том, что вы ссылаетесь на узел 22 в ваших данных edg, который в «индексе на основе 0 " указывает на 23-ю строку вашего фрейма данных vert, которой не существует.

Как было указано, это, вероятно, связано с тем, что индексация основана на 1 и должна быть преобразована, что можно легко сделать с помощью

edg$Gene1 <- edg$Gene1 - 1
edg$Gene2 <- edg$Gene2 - 1

В качестве альтернативы можно было бы сослаться на другой узел, который по какой-либо причине не попал во фрейм данных vert, и в этом случае этот узел нужно было бы добавить во фрейм данных vert, что можно было легко сделать с помощью (для пример)...

vert <- rbind(vert, c(23,1,1))

Вы можете проверить, ссылаетесь ли вы на узел в ваших данных edj, который не существует в ваших данных vert, с помощью чего-то вроде...

all(unique(c(edg$Gene1, edg$Gene2)) %in% (1:nrow(vert) - 1))
# [1] FALSE

который должен вернуть TRUE. Если нет, то что-то не так.

Вы можете определить, какие узлы упоминаются в ваших данных edg, но не существуют в ваших данных vert с помощью...

unique(c(edg$Gene1, edg$Gene2))[which(!unique(c(edg$Gene1, edg$Gene2)) %in% (1:nrow(vert) - 1))]
# [1] 22

полностью воспроизводимый пример настройки индексов в edg на «0»

edg <- read.csv(header = TRUE, colClasses = 'character', text = '
Gene1,Gene2,Prob
1,22,3
2,22,6
3,22,6
4,22,9
5,22,3
6,22,4
7,22,8
8,22,4
9,22,6
10,22,8
11,22,6
12,22,10
13,22,6
14,22,3
15,22,6
16,22,6
17,22,0
18,22,4
19,22,6
20,22,4
')

vert <- read.csv(header = TRUE, colClasses = 'character', text = '
Symbol,Chr,Expr
1,21,9
2,17,10
3,17,0
4,20,0
5,6,9
6,5,11
7,12,0
8,1,20
9,17,11
10,17,7
11,17,11
12,10,0
13,17,0
14,7,7
15,17,6
16,17,0
17,2,5
18,5,10
19,17,10
20,17,9
21,12,4
22,3,2
')

# cast to numeric just to be sure
edg$Gene1 <- as.numeric(edg$Gene1)
edg$Gene2 <- as.numeric(edg$Gene2)

# adjust the indices so they're "0-based"
edg$Gene1 <- edg$Gene1 - 1
edg$Gene2 <- edg$Gene2 - 1

# Nodesize is also necessarily numeric
vert$Expr <- as.numeric(vert$Expr)

library(networkD3)
forceNetwork(Links = edg, Nodes = vert, Source = "Gene1", Target = "Gene2", 
         Value = "Prob", NodeID = "Symbol", Group = "Chr", opacity = 0.7,
         Nodesize = "Expr", zoom = TRUE, legend = TRUE)


полностью воспроизводимый пример добавления узла в vert

edg <- read.csv(header = TRUE, colClasses = 'character', text = '
Gene1,Gene2,Prob
1,22,3
2,22,6
3,22,6
4,22,9
5,22,3
6,22,4
7,22,8
8,22,4
9,22,6
10,22,8
11,22,6
12,22,10
13,22,6
14,22,3
15,22,6
16,22,6
17,22,0
18,22,4
19,22,6
20,22,4
')

vert <- read.csv(header = TRUE, colClasses = 'character', text = '
Symbol,Chr,Expr
1,21,9
2,17,10
3,17,0
4,20,0
5,6,9
6,5,11
7,12,0
8,1,20
9,17,11
10,17,7
11,17,11
12,10,0
13,17,0
14,7,7
15,17,6
16,17,0
17,2,5
18,5,10
19,17,10
20,17,9
21,12,4
22,3,2
')

# cast to numeric just to be sure
edg$Gene1 <- as.numeric(edg$Gene1)
edg$Gene2 <- as.numeric(edg$Gene2)
vert$Expr <- as.numeric(vert$Expr)

# add another node to the Nodes data frame
vert <- rbind(vert, c(23,1,1))

library(networkD3)
forceNetwork(Links = edg, Nodes = vert, Source = "Gene1", Target = "Gene2", 
         Value = "Prob", NodeID = "Symbol", Group = "Chr", opacity = 0.7,
         Nodesize = "Expr", zoom = TRUE, legend = TRUE)

person CJ Yetman    schedule 23.09.2018

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

edg$Gene1<-factor(edg$Gene1,levels=vert$Symbol)
edg$Gene2<-factor(edg$Gene2,levels=vert$Symbol)
edg$source<-as.numeric(edg$Gene1)-1
edg$target<-as.numeric(edg$Gene2)-1

чтобы исходный и целевой векторы имели согласованные уровни факторов в виде имен узлов (vert$Symbol), затем

forceNetwork( Links = edg, Nodes = vert, Source = "source", Target = "target", 
          Value = "Prob", NodeID = "Symbol", Group = "Chr", opacity = 0.7,
          colourScale = "d3.scale.category20b()", Nodesize = "Expr", zoom = T,
          legend = T )

работает на меня.

Надеюсь, это полезно.

person Rui    schedule 21.11.2018