создание пар для сетевого анализа

Из своего набора данных я пытаюсь составить пары на основе рейтинга. мои данные выглядят так

ID     grp      rank
1      grp1       1
1      grp2       1
1      grp3       2
2      grp1       1
2      grp2       2
2      grp2       2
2      grp2       2
2      grp3       2
2      grp1       3  

Результат, к которому я стремлюсь, следующий: для каждого идентификатора

  • если rank = 1, то grp в источнике и получателе одинаковы = grp
  • If rank is different from 1 then
    • source = take grp from previous rank
    • назначение = взять группу из текущего рейтинга. Если для одного и того же рейтинга существует более одной группы, необходимо создать дополнительную строку, чтобы каждая пара была представлена.

Это выглядит следующим образом

ID     rank     source  destination
 1       1       grp1        grp1
 1       1       grp2        grp2
 1       2       grp1        grp3
 1       2       grp2        grp3
 2       1       grp1        grp1
 2       2       grp1        grp2 
 2       2       grp1        grp2
 2       2       grp1        grp2
 2       2       grp1        grp3
 2       3       grp2        grp1
 2       3       grp3        grp1

Я начал с цикла for и операторов if_else, но застрял. Любая помощь приветствуется! Спасибо заранее.


person JL B    schedule 18.12.2018    source источник


Ответы (1)


Мы можем сделать следующее:

df %>% group_by(ID) %>% 
  do(map_dfr(1:nrow(.), function(i)
    data.frame(.[i, -2], source = if(.$rank[i] == 1) .$grp[i] else unique(.$grp[.$rank == .$rank[i] - 1]), 
               destination = .$grp[i])))
# A tibble: 11 x 4
# Groups:   ID [2]
#       ID  rank source destination
#    <int> <int> <fct>  <fct>      
#  1     1     1 grp1   grp1       
#  2     1     1 grp2   grp2       
#  3     1     2 grp1   grp3       
#  4     1     2 grp2   grp3       
#  5     2     1 grp1   grp1       
#  6     2     2 grp1   grp2       
#  7     2     2 grp1   grp2       
#  8     2     2 grp1   grp2       
#  9     2     2 grp1   grp3       
# 10     2     3 grp2   grp1       
# 11     2     3 grp3   grp1 

Мы группируем по ID, а затем просматриваем каждую строку данной группы. Затем для каждой строки мы создаем новый фрейм данных в соответствии с вашими правилами.

person Julius Vainora    schedule 18.12.2018
comment
Привет, Юлий, спасибо за ответ, время и усилия!!! Я бы не понял этого сам, но узнал кое-что новое благодаря вашему ответу. Это решает мою проблему. - person JL B; 18.12.2018
comment
@JLB, нет проблем, я рад, что это помогло. Вы действительно могли бы использовать для этого цикл for, единственное неудобство, заключающееся в том, что в конечном итоге у вас был бы список фреймов данных, а затем вам нужно было бы вручную их объединить, что делается для вас автоматически с моим решением. - person Julius Vainora; 18.12.2018
comment
да, это были я застрял. Я не мог понять, как мне пришлось снова собирать все вместе ... спасибо! - person JL B; 18.12.2018
comment
@JLB, на будущее: если l - это список фреймов данных для объединения по вертикали, do.call(rbind, l) в базе R или bind_rows(l) с tidyverse сделают эту работу. - person Julius Vainora; 18.12.2018