0

作为网络分析的新手,我正在努力将要绘制的事件级数据集转换为正确的形状。我很感谢任何提示/线索/等。到目前为止,我所做的大致遵循介绍。

有问题的数据集包含政党 Jobbik 组织的事件。由唯一 id ( id) 定义的每个事件都有关联的组织发起人 ( org_names) 及其类型 ( org)。org_1org_2org_names1和之间没有层次结构org_names2

最初,数据集采用宽格式。虽然我不确定这是否是我应该做的,但我要做的第一步是将数据转换为长格式并清理一些字符串。这是读取数据并将其转换为长格式的代码:

jobbik <- read.csv("http://eborbath.github.io/stackoverflow/jobbik.csv")


library(tidyverse)
library(stringr)
library(igraph)

# long format

jobbik <- reshape(as.data.frame(jobbik), dir='long',
                  varying=list(c(3:13), c(14:24)),
                  v.names=c('org_names', 'org'), times = c(as.character(seq(1:11))))
jobbik$org <- str_trim(jobbik$org, side="both")
jobbik$org_names <- str_trim(jobbik$org_names, side="both")
jobbik <- jobbik %>%
  filter(!(org=="no other organizer" & org_names=="")) %>%
  filter(!(org=="JOBBIK" & org_names %in% c("Jobbik",
                                            "Jobbik Magyarországért Mozgalom",
                                            "",
                                            "JObbik",
                                            "jobbik",
                                            "aktivisté Jobbiku",
                                            "a Jobbik"))) %>% 
  mutate(org_names=ifelse(org_names=="", org, org_names)) %>%
  distinct(.)

在下一步中,我想创建网络数据集。为此,我计算了每个独特组织参与 Jobbik 活动的次数。添加 Jobbik 作为每条边的一侧并用 igraph 绘制数据:

network <- jobbik %>%
  select(id, org_names) %>% 
  group_by(org_names) %>%
  summarise(weight = n()) %>% 
  ungroup() %>% 
  mutate(from=1,
         org_names=as.factor(org_names)) %>% 
  mutate(org_id=as.numeric(factor(org_names)))

edges <- network %>% select(from, org_id, weight)
nodes <- network %>% select(org_id, org_names) %>% 
  mutate(org_names=as.character(org_names))


routes_igraph <- graph_from_data_frame(d = edges, vertices = nodes, directed = FALSE)

plot(routes_igraph, layout = layout_with_graphopt)

虽然它运行并创建了网络,但它只能让我了解每个独特的组织和 Jobbik 之间的关系,而不是这些不涉及 Jobbik 的组织之间的关系。我意识到错误出在我所做的数据转换中,我应该使用事件级别的信息来计算每个组织对参与组织某事的次数,然后绘制该数据。不幸的是,虽然我不知道如何到达那里。我很感激任何帮助。

4

1 回答 1

1

我并不是网络分析方面的专家,igraph尤其是。但我认为这样的事情可能会有所帮助。

我更改了您分析的预处理部分,因为我在某种程度上发现了一些并发症:

  1. 匈牙利语的编码:找到正确的编码需要时间(见locale = 'cp1250电话read_csv
  2. 收集后,我已更改org_name*为;orgorg*type
  3. 我用chop它来更容易spread-> unnest;
  4. 我试图filter缩短通话时间,但没有取得很大成功;
  5. stringr::str_to_title()用来统一orgvar,因为有相同的名称,只是名称的第 n 个单词是否大写;
  6. 我用var 中的值coalesce填充varNA的 s 。orgtype

    library(tidyverse)
    library(magrittr)
    library(igraph)
    
    jobbik <- read_csv(
      "http://eborbath.github.io/stackoverflow/jobbik.csv", 
      trim_ws = T, 
      locale = locale(encoding = 'cp1250')
      )
    
    jobbik %<>%
      gather('key', 'val', -c('id', 'date')) %>%
      mutate(
        key = case_when(
          grepl('^org_names\\d+$', key) ~ 'org',
          grepl('^org\\d+$',       key) ~ 'type',
          TRUE                         ~ key
        )
      ) %>%
      chop(val) %>%
      spread(key, val) %>%
      unnest(c(org, type)) %>%
      filter(
        !(is.na(org) & (type == 'no other organizer')) &
        !((is.na(org) | grepl('.*jobbik.*', org, T  )) & (type == 'JOBBIK'))
      ) %>%
      mutate(org = str_to_title(coalesce(org, type)))
    

为了形成图边的数据框,我id对事件进行分组,过滤掉仅由一个组织支持的所有事件(因此与其他组织没有联系),最后我在具有功能id的组织之间创建对combn. 结果是 character vector Org A-Org B,在取消嵌套之后,我将其分成 cols并from用作拆分(如果 org. 的名称中有符号,这可能很危险)。如果有的话,我也会过滤掉所有的自循环。最后一个操作是,计算每个单独配对在 Jobbik 会议列表中出现的频率。我将其分配给 ,因为在绘图时,会将其用作边缘的宽度。to--countwidthigraph::plot

ed <- jobbik %>%
  group_by(id) %>%
  filter(n() > 1) %>%
  summarise(edge = list(combn(org, 2, paste, collapse = '-'))) %>%
  unnest(edge) %>%
  separate(edge, into = c('from', 'to'), sep = '-') %>%
  filter(from != to) %>%
  count(from, to, name = width)

对顶点执行类似的分析。我在这里添加了顶点的额外信息,即 event id, ,您可以进一步使用的date组织- 映射给定 org 的次数。支持 Jobbik 和后一个绘图的一些附加图形参数。typecolor

nd <- jobbik %>%
  filter(org %in% c(ed$from, ed$to)) %>%
  group_by(name = org) %>%
  summarise(
    id   = sprintf('Event ids: %s', paste(id, collapse = ', ')),
    date = sprintf('Event dates: %s', paste(date, collapse = ', ')),
    type = sprintf('Org. type: %s',   paste(type, collapse = '; ')),
    color = n() 
  ) %>%
  ungroup() %>%
  mutate(
    color = heat.colors(10)[cut(color, 10)],
    frame.color = NA,
    label.dist = 1,
    label.cex = .5,
    label.color = 'gray10'
  )

有了这些数据,我们可以使用graph_from_data_frame()函数制作无向图:

g <- graph_from_data_frame(ed, F, nd)
vertex_attr(g, 'size') <- degree(g, mode = 'all')

在上面的第二行中,我添加了顶点属性size以将顶点的度数映射到顶点的大小。

最后要绘制社区,我可以这样做:

plot(
  g,
  edge.curved  = .2,
  layout = layout_with_kk,
  asp = 1,
  main = 'Jobbik interaction network',
  )

乔比克

于 2020-01-19T16:13:21.137 回答