我使用dplyr和tidyr函数“整理”了R中的数据,并创建了如下数据框架:
df <- data.frame(PROD = c("A","A","A","A"), REJECT = c("YES","YES","NO","NO"),ALT_PROD = c("A","B","C","D"), VALUE = c(100,50,400,500))我希望根据上面的值绘制一个3节的sankey图。我发现的大多数示例都使用了2节图(从->到),但我希望包括中间部分“拒绝”。我还找到了包含多个部分的示例,但由于我在R.
有一个选项可以使用flipPlot包,但是由于包更新问题,我在从GitHub安装软件包时遇到了问题:
Error: Failed to install 'flipPlots' from GitHub:
  Failed to install 'flipTransformations' from GitHub:
  Failed to install 'flipFormat' from GitHub:
  (converted from warning) cannot remove prior installation of package ‘jsonlite’ 我以前使用过networkD3包来创建一个两节图,我真的希望更好地理解如何扩展这个包来构建一个3节图。
发布于 2020-08-06 11:36:47
您需要构建符合'source', 'target', ...样式的链接数据框架。在您的示例中,每个连续列(值列除外)都是上一列的目标。您可以通过从每个列的顺序推断每个步骤的顺序来重塑数据.
library(networkD3)
library(dplyr)
library(tidyr)
df <- data.frame(PROD = c("A","A","A","A"), 
                 REJECT = c("YES","YES","NO","NO"),
                 ALT_PROD = c("A","B","C","D"), 
                 VALUE = c(100,50,400,500))
links <-
  df %>% 
  as_tibble() %>% 
  mutate(row = row_number()) %>% 
  pivot_longer(cols = c(-row, -VALUE),
               names_to = 'column', values_to = 'source') %>% 
  mutate(column = match(column, names(df))) %>% 
  mutate(source = paste0(source, '__', column)) %>% 
  group_by(row) %>% 
  mutate(target = lead(source, order_by = column)) %>% 
  drop_na(target, source) %>% 
  group_by(source, target) %>% 
  summarise(value = sum(VALUE), .groups = 'drop')
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)
sankeyNetwork(Links = links, Nodes = nodes, Source = "source", 
              Target = "target", Value = "value", NodeID = "name")为了使这个过程更清楚,下面是您需要构建的links数据框架在流程中的每一个重要步骤之后的样子。
df %>% 
  as_tibble() %>% 
  mutate(row = row_number())
#> # A tibble: 4 x 5
#>   PROD  REJECT ALT_PROD VALUE   row
#>   <chr> <chr>  <chr>    <dbl> <int>
#> 1 A     YES    A          100     1
#> 2 A     YES    B           50     2
#> 3 A     NO     C          400     3
#> 4 A     NO     D          500     4
df %>% 
  as_tibble() %>% 
  mutate(row = row_number()) %>% 
  pivot_longer(cols = c(-row, -VALUE),
               names_to = 'column', values_to = 'source')
#> # A tibble: 12 x 4
#>    VALUE   row column   source
#>    <dbl> <int> <chr>    <chr> 
#>  1   100     1 PROD     A     
#>  2   100     1 REJECT   YES   
#>  3   100     1 ALT_PROD A     
#>  4    50     2 PROD     A     
#>  5    50     2 REJECT   YES   
#>  6    50     2 ALT_PROD B     
#>  7   400     3 PROD     A     
#>  8   400     3 REJECT   NO    
#>  9   400     3 ALT_PROD C     
#> 10   500     4 PROD     A     
#> 11   500     4 REJECT   NO    
#> 12   500     4 ALT_PROD D
df %>% 
  as_tibble() %>% 
  mutate(row = row_number()) %>% 
  pivot_longer(cols = c(-row, -VALUE),
               names_to = 'column', values_to = 'source') %>% 
  mutate(column = match(column, names(df))) %>% 
  mutate(source = paste0(source, '__', column))
#> # A tibble: 12 x 4
#>    VALUE   row column source
#>    <dbl> <int>  <int> <chr> 
#>  1   100     1      1 A__1  
#>  2   100     1      2 YES__2
#>  3   100     1      3 A__3  
#>  4    50     2      1 A__1  
#>  5    50     2      2 YES__2
#>  6    50     2      3 B__3  
#>  7   400     3      1 A__1  
#>  8   400     3      2 NO__2 
#>  9   400     3      3 C__3  
#> 10   500     4      1 A__1  
#> 11   500     4      2 NO__2 
#> 12   500     4      3 D__3
df %>% 
  as_tibble() %>% 
  mutate(row = row_number()) %>% 
  pivot_longer(cols = c(-row, -VALUE),
               names_to = 'column', values_to = 'source') %>% 
  mutate(column = match(column, names(df))) %>% 
  mutate(source = paste0(source, '__', column)) %>% 
  group_by(row) %>% 
  mutate(target = lead(source, order_by = column))
#> # A tibble: 12 x 5
#> # Groups:   row [4]
#>    VALUE   row column source target
#>    <dbl> <int>  <int> <chr>  <chr> 
#>  1   100     1      1 A__1   YES__2
#>  2   100     1      2 YES__2 A__3  
#>  3   100     1      3 A__3   <NA>  
#>  4    50     2      1 A__1   YES__2
#>  5    50     2      2 YES__2 B__3  
#>  6    50     2      3 B__3   <NA>  
#>  7   400     3      1 A__1   NO__2 
#>  8   400     3      2 NO__2  C__3  
#>  9   400     3      3 C__3   <NA>  
#> 10   500     4      1 A__1   NO__2 
#> 11   500     4      2 NO__2  D__3  
#> 12   500     4      3 D__3   <NA>
df %>% 
  as_tibble() %>% 
  mutate(row = row_number()) %>% 
  pivot_longer(cols = c(-row, -VALUE),
               names_to = 'column', values_to = 'source') %>% 
  mutate(column = match(column, names(df))) %>% 
  mutate(source = paste0(source, '__', column)) %>% 
  group_by(row) %>% 
  mutate(target = lead(source, order_by = column)) %>% 
  drop_na(target, source)
#> # A tibble: 8 x 5
#> # Groups:   row [4]
#>   VALUE   row column source target
#>   <dbl> <int>  <int> <chr>  <chr> 
#> 1   100     1      1 A__1   YES__2
#> 2   100     1      2 YES__2 A__3  
#> 3    50     2      1 A__1   YES__2
#> 4    50     2      2 YES__2 B__3  
#> 5   400     3      1 A__1   NO__2 
#> 6   400     3      2 NO__2  C__3  
#> 7   500     4      1 A__1   NO__2 
#> 8   500     4      2 NO__2  D__3
df %>% 
  as_tibble() %>% 
  mutate(row = row_number()) %>% 
  pivot_longer(cols = c(-row, -VALUE),
               names_to = 'column', values_to = 'source') %>% 
  mutate(column = match(column, names(df))) %>% 
  mutate(source = paste0(source, '__', column)) %>% 
  group_by(row) %>% 
  mutate(target = lead(source, order_by = column)) %>% 
  drop_na(target, source) %>% 
  group_by(source, target) %>% 
  summarise(value = sum(VALUE), .groups = 'drop')
#> # A tibble: 6 x 3
#>   source target value
#>   <chr>  <chr>  <dbl>
#> 1 A__1   NO__2    900
#> 2 A__1   YES__2   150
#> 3 NO__2  C__3     400
#> 4 NO__2  D__3     500
#> 5 YES__2 A__3     100
#> 6 YES__2 B__3      50https://stackoverflow.com/questions/63255589
复制相似问题