Как убрать детей в кадре данных для построения сети в R? - PullRequest
3 голосов
/ 25 марта 2020

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

parent <- c("A","A","A","B","B","E")
child <-  c("B","C","D","C","D","D")
df <- data.frame(parent,child)

Я хотел бы удалить дочерних детей в df, чтобы я мог использовать igraph для построения своей сети. Поэтому я хочу, чтобы мои данные выглядели как df_net:

parent <- c("A","B","B","E")
child <-  c("B","C","D","D")
df_net <- data.frame(parent,child)
net <- graph_from_data_frame(df_net,directed = T)
plot(net)

Рисунок графика (net)

Что лучше способ (автоматически) удалить ненужные строки df? (У меня есть несколько фреймов данных, содержащих до 100 строк, поэтому удаление строк вручную - это не вариант.)

Моей первой идеей было использование while l oop для поиска родителей на каждом этапе иерархии. , Я думал, что смогу использовать это для фильтрации строк в df. Но я не думаю, что я на правильном пути здесь. Любые идеи приветствуются!

`%notin%` <- Negate(`%in%`)
i <- nrow(df)
y <- list()
z <- list()
j <- 1
while (i > 0) {
  v <- unique(df$parent[!(df$parent %in% df$child)]) # find mismatch (only in parent, not in child)
  df <- df %>% filter(parent %notin% v)
  print(v)
  y[[j]] <- v
  z[[j]] <- df
  i = nrow(df)
  j = j+1
}

Ответы [ 2 ]

2 голосов
/ 25 марта 2020

Это dplyr решение:

library(dplyr)

# get data
parent <- c("A","A","A","B","B","E")
child <-  c("B","C","D","C","D","D")
df <- data.frame(parent,child, stringsAsFactors = FALSE)

# remove rows that are not directly related
new_df <- anti_join(df,
          left_join(df,df,by=c("child"="parent")) %>% 
  select(parent,child=child.y) %>% 
  na.omit()) 

new_df
  parent child
1      A     B
2      B     C
3      B     D
4      E     D
1 голос
/ 25 марта 2020

Как насчет использования igraph для определения путей между людьми, и, если их больше 1, удалить это соединение?

library(igraph)
parent <- c("A","A","A","B","B","E")
child <-  c("B","C","D","C","D","D")
df <- data.frame(parent,child)
net <- graph_from_data_frame(df,directed = T)
df <- df[apply(df,1,function(x){length(all_simple_paths(net,x[1],x[2]))}) == 1,]
df
  parent child
1      A     B
4      B     C
5      B     D
6      E     D

Боюсь, что это может быть довольно медленно на очень больших графиках, так что если кто-нибудь имеет решение data.table, которое может быть лучше.

...