Создайте график с параллельными координатами относительно количества вхождений в r

У меня есть DF, как показано ниже. он содержит информацию о двух студентах за 3 семестра и предметах, независимо от того, сдали они экзамен или нет.
Я хотел бы нарисовать параллельную координату следа студентов. Я хочу увидеть, какой путь пройден, чтобы достичь конца.

ID  term  subject  result
1    1     math01    fail
1    1     Phys01    pass
1    1     chem01    pass
1    2     math01    pass
1    2     math02    fail
1    3     math02    fail
1    3     cmp01     pass
2    1     math01    fail
2    1     phys01    pass
2    2     math01    pass
2    2     math02    pass
2    3     cmp01     pass

желаемый результат будет аналогичен изображению ниже.
Каждый блок в каждом термине показывает выбранный псевдоним субъекта с resultстолбцом (провал или пройдено). размер блока должен соответствовать номеру взятого предмета. например, если большинство учащихся не справляются с заданием по математике01 в 1-м семестре, блок math01fail должен быть самым большим блоком ниже 1-го семестра.

Соединительная линия соединяет то, какие предметы студенты изучали в этом семестре, со следующим семестром. Толщина линии соответствует количеству соединений в этой точке. например, если многие учащиеся не сдают математику01 (math01fail) в 1-м семестре и пересдают математику 01 во 2-м семестре и сдают его (math01pass), соединительная линия между math01fail и math01pass должна быть толще в зависимости от количества вхождений.

Как я могу создать такой сюжет в R? введите здесь описание изображения


person Cina    schedule 26.11.2018    source источник
comment
Я не уверен, что понимаю ваш ожидаемый график параллельных координат. Связь от Math01fail к Math01pass толще, потому что есть два субъекта. Все идет нормально. Но почему соединение от Phys01pass до Math01pass толще? Есть только один предмет с этими категориями?   -  person Maurits Evers    schedule 27.11.2018
comment
@MauritsEvers, потому что у обоих студентов есть Phys01pass в семестре 1 и Math01pass в семестре 2. аналогично, оба студента имеют Math01fail в семестре 1 и Math01pass в семестре 2. извините если не понятно написал   -  person Cina    schedule 27.11.2018
comment
Все еще в замешательстве. Какой столбец обозначает предмет (студент). Это ID?   -  person Maurits Evers    schedule 28.11.2018
comment
@MauritsEvers, извините за путаницу. да, каждый идентификатор представляет студента.   -  person Cina    schedule 29.11.2018


Ответы (1)


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

Вот что я бы сделал:

  1. Начните с загрузки необходимых библиотек

    library(tidyverse)
    library(igraph)
    
  2. Сначала мы определяем список ребер нашего графа. Для этого мы выполняем самосоединение df на ID и выбираем строки, соответствующие последовательным (возрастающим) терминам. Затем каждая строка соответствует ссылке от семестра i до i+1 для каждого учащегося.

    el <- left_join(df, df, by = "ID") %>%
        filter(term.x == term.y - 1) %>%
        mutate_at(vars(starts_with("term")), funs(paste0("term", .))) %>%
        unite(from, term.x, subject.x, result.x, sep = "\n") %>%
        unite(to, term.y, subject.y, result.y, sep = "\n") %>%
        select(from, to) %>%
        group_by(from, to) %>%
        summarise(weight = (n() - 1) * 5 + 1)
    

    Мы добавляем столбец веса, который пропорционален количеству студентов для каждого ребра. Причина, по которой мы не делаем просто weight = n(), связана исключительно с эстетикой, когда нам нравится иметь более толстые линии для> 1 ученика.

  3. Далее мы определяем список узлов. Ключевым моментом здесь является добавление столбцов x и y, которые будут определять расположение узлов сетки.

    nl <- df %>%
        mutate(term = paste0("term", term)) %>%
        arrange(term) %>%
        distinct(term, subject, result) %>%
        mutate(x = as.integer(as.factor(term))) %>%
        group_by(term) %>%
        mutate(y = 1:n()) %>%
        unite(node, term, subject, result, sep = "\n")
    

    Обратите внимание, что записи в первом столбце nl должны совпадать с записями в первых двух столбцах el.

  4. Теперь мы готовы построить igraph из обоих data.frame и построить график.

    gr <- graph_from_data_frame(d = el, vertices = nl, directed = F)
    plot(
        gr,
        edge.width = E(gr)$weight,
        vertex.shape = "rectangle",
        vertex.size = 50, vertex.size2 = 50,
        vertex.color = "white",
        vertex.label.family = "sans",
        vertex.label.cex = 0.7)
    

    введите здесь описание изображения

    Полученный график может потребовать дополнительной настройки/полировки, но это должно помочь вам начать работу.

person Maurits Evers    schedule 28.11.2018