Создание графа igraph из сгруппированных данных dplyr - PullRequest
0 голосов
/ 03 октября 2018

Моя цель - создать объект графа igraph, который я позже смогу использовать для построения графика с ggraph.

Мои аккуратные данные - это счета-фактуры, каждый из которых содержит различное количество элементов.n - количество вхождений ровно одного счета в исходном образце.Например, в следующем счете-фактуре тип 1, который включает хлеб, масло и яйца, был выставлен 10 раз.

#library(tidyverse)
data <- tibble(invoicetype = c(1,1,1,2,2,3,3,4,4,4,4,4,5,5,6,7,7,8,8,8,9,9), 
               item = c("bread", "butter", "eggs", "bread", "coke", "coke", "eggs", 
                        "bread", "butter","coke", "pasta", "water", "coke", "water", 
                        "coke", "bread", "butter", "eggs", "coke", "water", "pasta", 
                        "bread"),
               n = c(10,10,10,8,8,7,7,4,4,4,4,4,3,3,3,2,2,1,1,1,1,1))

Я хочу создать объект igraph, который учитывает, сколько раз каждый элемент был объединен втот же счет с любым другим предметом.

Вопрос: есть ли простой способ сделать это?

Мое громоздкое решение:

Решение, которое я придумала, но оно не изящно и не работает с моими фактическими (большими) данными.

data_spreaded <- data %>% group_by(invoicetype, n) %>% 
  summarise(item1 = item[1], item2 = item[2], item3 = item[3], 
            item4 = item[4], item5 = item[5])

combinations <- tibble()
for (g in 1:nrow(data_spreaded)) {
  for (i in 3:ncol(data_spreaded)) {
    for (j in 3:ncol(data_spreaded)) {
      if (i == j) { next }
      combinations <- 
        bind_rows(combinations,
                  tibble(from = data_spreaded[g,i] %>% pull(),
                         to = data_spreaded[g,j] %>% pull(),
                         invoicetype = data_spreaded[g,1] %>% pull(),
                         n = data_spreaded[g,2]%>% pull()))
    }
  }
}

combinations <- combinations %>% 
  distinct() %>% # remove the double counted
  filter(!is.na(from), !is.na(to)) %>% # remove empty combinations
  group_by(from, to) %>% 
  summarise(n = sum(n)) %>% 
  ungroup()

#library(igraph)
g <- graph_from_data_frame(combinations, directed = F)

Для построения графика с использованием ggraph я использую:

E(g)$weight <- combinations$n

#library(ggraph)
set.seed(123)
ggraph(g, layout = "with_kk") + 
  geom_node_point() + 
  geom_node_text(aes(label = name), repel = T) +
  geom_edge_link(aes(color = weight, label = n))

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Я обычно подгоняю что-то подобное к подобным ситуациям.

library(tidyverse)

data <- tibble(invoicetype = c(1,1,1,2,2,3,3,4,4,4,4,4,5,5,6,7,7,8,8,8,9,9), 
               item = c("bread", "butter", "eggs", "bread", "coke", "coke", "eggs", 
                        "bread", "butter","coke", "pasta", "water", "coke", "water", 
                        "coke", "bread", "butter", "eggs", "coke", "water", "pasta", 
                        "bread"),
               n = c(10,10,10,8,8,7,7,4,4,4,4,4,3,3,3,2,2,1,1,1,1,1))


data %>% 
  mutate(item2 = item) %>%                      # make a second item column
  group_by(invoicetype) %>%                     
  expand(item, item2, nesting(n)) %>%           # get all in-group combinations
  ungroup() %>%
  filter(item != item2) %>%                     # drop loops
  mutate(from = map2_chr(item, item2, min),     # for undirected, sort dyad's names...
         to = map2_chr(item, item2, max)) %>%   # ... alphabetically
  distinct(from, to, n) %>%                     # drop duplicate rows and unused columns
  group_by(from, to) %>% 
  summarise(weight = sum(n)) %>%
  ungroup()

#> # A tibble: 14 x 3
#>    from   to     weight
#>    <chr>  <chr>   <dbl>
#>  1 bread  butter     16
#>  2 bread  coke       12
#>  3 bread  eggs       10
#>  4 bread  pasta       5
#>  5 bread  water       4
#>  6 butter coke        4
#>  7 butter eggs       10
#>  8 butter pasta       4
#>  9 butter water       4
#> 10 coke   eggs        8
#> 11 coke   pasta       4
#> 12 coke   water       8
#> 13 eggs   water       1
#> 14 pasta  water       4
0 голосов
/ 03 октября 2018

Можно сэкономить много времени, если вы просто оставляете данные присоединенными к себе.За этим типом рабочего процесса следует множество крайних списков:

combo <- data %>%
  #join the data to itself
  left_join(data, by = c('invoicetype', 'n')) %>%
  #this is undirected so x %--% y is the same as y %--% x
  filter(item.x < item.y) %>%
  group_by(item.x, item.y) %>%
  summarize(n = sum(n))

Вот график

g <- graph_from_data_frame(combo2, directed = F)

g_strength <- strength(g, weights = E(g)$n)

set.seed(1234)
plot(g,
     edge.width = E(g)$n/max(E(g)$n) * 10,
     vertex.size = g_strength/max(g_strength) * 20)

food connections

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

...