Диаграмма Санки с несколькими столбцами и весом столбца - с помощью пакета NetworkD3 - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь создать интерактивный Sankey с пакетом . У меня есть набор данных с восемью столбцами.

df <- read.csv(header = TRUE, as.is = TRUE, text = '
clientcode,year1,year2,year3,year4,year5,year6,year7
1,DBC,DBBC,DBBC,DBC,DBC,"Not in care","Not in care"
2,DBC,DBBC,DBBC,"Not in care","Not in care","Not in care","Not in care"
3,DBC,DBBC,"Not in care","Not in care","Not in care","Not in care","Not in care"
4,DBC,DBBC,"Not in care","Not in care","Not in care","Not in care","Not in care"
5,DBC,DBBC,DBBC,"Not in care","Not in care","Not in care","Not in care"
')

Я использую приведенный ниже код в этом сообщении, начиная с "Этот вопрос часто возникает ...": https://stackoverflow.com/a/52237151/4389763

Это код, который у меня есть:

df <- df %>% select(year1,year2,year3,year4,year5,year6,year7) 

links <-
df %>%
mutate(row = row_number()) %>%
gather('column', 'source', -row) %>%
mutate(column = match(column, names(df))) %>%
group_by(row) %>%
arrange(column) %>%
mutate(target = lead(source)) %>%
ungroup() %>%
filter(!is.na(target))

links <-
links %>%
mutate(source = paste0(source, '_', column)) %>%
mutate(target = paste0(target, '_', column + 1)) %>%
select(source, target)

nodes <- data.frame(name = unique(c(links$source, links$target)))

links$source <- match(links$source, nodes$name) - 1
links$target <- match(links$target, nodes$name) - 1
links$value <- 1

nodes$name <- sub('_[0-9]+$', '', nodes$name)

library(networkD3)
library(htmlwidgets)

sankeyNetwork(Links = links, Nodes = nodes, Source = 'source',
          Target = 'target', Value = 'value', NodeID = 'name')

Но я не знаю, как добавить значение потока. Например, от DBC до DBBC происходит пять раз в год1 - год2 И DBBC для DBBC происходит три раза от года2 к году3. С кодом выше я вижу каждое вхождение как 1, и я хотел бы видеть общее значение потока.

Как и этот пример Санки. Где вы можете увидеть общее количество, например, от group_A до group_C, а не каждое вхождение.

А можно ли увидеть проценты в мышке над? Например, Год1 = от DBC до Года2 = значение DBBC равно 5 из 5, а процент составляет 100%.

Может кто-нибудь мне помочь? Спасибо.

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

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

df <- read.csv(header = TRUE, as.is = TRUE, text = '
clientcode,year1,year2,year3,year4,year5,year6,year7
1,DBC,DBBC,DBBC,DBC,DBC,"Not in care","Not in care"
2,DBC,DBBC,DBBC,"Not in care","Not in care","Not in care","Not in care"
3,DBC,DBBC,"Not in care","Not in care","Not in care","Not in care","Not in care"
4,DBC,DBBC,"Not in care","Not in care","Not in care","Not in care","Not in care"
5,DBC,DBBC,DBBC,"Not in care","Not in care","Not in care","Not in care"
')

library(dplyr)
library(tidyr)

links <-
  df %>%
  select(-clientcode) %>% 
  mutate(row = row_number()) %>%
  gather('column', 'source', -row) %>%
  mutate(column = match(column, names(df))) %>%
  group_by(row) %>%
  arrange(column) %>%
  mutate(target = lead(source)) %>%
  ungroup() %>%
  filter(!is.na(target)) %>%
  mutate(source = paste0(source, '_', column)) %>%
  mutate(target = paste0(target, '_', column + 1)) %>%
  select(source, target)

links

# # A tibble: 30 x 2
#    source target       
#    <chr>  <chr>        
#  1 DBC_2  DBBC_3       
#  2 DBC_2  DBBC_3       
#  3 DBC_2  DBBC_3       
#  4 DBC_2  DBBC_3       
#  5 DBC_2  DBBC_3       
#  6 DBBC_3 DBBC_4       
#  7 DBBC_3 DBBC_4       
#  8 DBBC_3 Not in care_4
#  9 DBBC_3 Not in care_4
# 10 DBBC_3 DBBC_4       
# # ... with 20 more rows

Вторая часть вашего вопроса, по сути, с набором данных отдельных ссылок, как я могу объединить похожие ссылки в одну ссылку со столбцом значения, показывающим, сколько отдельных ссылок было объединено в одну ссылку.Этого можно достичь, сгруппировав столбцы source и target и суммировав их с количеством строк.

links %>% 
  group_by(source, target) %>% 
  summarise(value = n())

# # A tibble: 11 x 3
# # Groups:   source [?]
#    source        target        value
#    <chr>         <chr>         <int>
#  1 DBBC_3        DBBC_4            3
#  2 DBBC_3        Not in care_4     2
#  3 DBBC_4        DBC_5             1
#  4 DBBC_4        Not in care_5     2
#  5 DBC_2         DBBC_3            5
#  6 DBC_5         DBC_6             1
#  7 DBC_6         Not in care_7     1
#  8 Not in care_4 Not in care_5     2
#  9 Not in care_5 Not in care_6     4
# 10 Not in care_6 Not in care_7     4
# 11 Not in care_7 Not in care_8     5

Поскольку вы хотите отобразить процент, а не счет, вы можете немного изменить его, чтобырассчитайте процентное соотношение всех ссылок в каждом году, а затем используйте параметр unit = "%", равный sankeyNetwork, чтобы он отображался правильно.

links <- 
  links %>% 
  group_by(source, target) %>% 
  summarise(value = n() / nrow(df) * 100)

links

# # A tibble: 11 x 3
# # Groups:   source [?]
#    source        target        value
#    <chr>         <chr>         <dbl>
#  1 DBBC_3        DBBC_4           60
#  2 DBBC_3        Not in care_4    40
#  3 DBBC_4        DBC_5            20
#  4 DBBC_4        Not in care_5    40
#  5 DBC_2         DBBC_3          100
#  6 DBC_5         DBC_6            20
#  7 DBC_6         Not in care_7    20
#  8 Not in care_4 Not in care_5    40
#  9 Not in care_5 Not in care_6    80
# 10 Not in care_6 Not in care_7    80
# 11 Not in care_7 Not in care_8   100

nodes <- data.frame(name = unique(c(links$source, links$target)))

links$source <- match(links$source, nodes$name) - 1
links$target <- match(links$target, nodes$name) - 1

nodes$name <- sub('_[0-9]+$', '', nodes$name)

library(networkD3)
library(htmlwidgets)

sankeyNetwork(Links = links, Nodes = nodes, Source = 'source',
              Target = 'target', Value = 'value', NodeID = 'name', 
              units = "%")

enter image description here

0 голосов
/ 18 сентября 2018

Я изменил код:

Вместо:

links$value <- 1

Новый код:

links <- links %>% group_by(source, target) %>% tally()
names(links)[3] <- "value"
...