R: От структуры панели до матрицы смежности или списка ребер? - PullRequest
0 голосов
/ 28 декабря 2018

Я пытаюсь преобразовать набор данных в структуре панели длинного формата в матрицу смежности или список границ для создания сетевых графиков.Набор данных содержит статьи, каждая из которых идентифицируется по идентификационному номеру.Каждая статья может появляться несколько раз под несколькими категориями.Следовательно, у меня сейчас длинная структура формата:

ID <- c(1,1,1,2,2,2,3,3)
Category <- c("A","B","C","B","E","H","C","E")
dat <- data.frame(ID,Category)

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

A B
A C
B C
B E
B H
E H
C E 

Редактировать: я пытался dat <- merge(ID, Category, by="Category"), но он возвращает сообщение об ошибке Error in fix.by(by.x, x) : 'by' must specify a uniquely valid column

Заранее спасибо

Обновление: я закончил тем, что использовал crossprod(table(dat)) из комментариев, но решение, предложенное Navy Cheng ниже, работает так же хорошо

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Так что, если вы хотите преобразовать свой data.frame в data.table, эту проблему можно решить довольно эффективно и аккуратно, и если у вас будет много строк, это будет намного быстрее.

    library(data.table)
    dat<-data.table(dat)

В основном выМожно применять функции к столбцам таблицы data.table в ячейке j и группировать в ячейке k.Таким образом, вы хотите, чтобы все комбинации категорий были взяты по две одновременно для каждого идентификатора, который выглядит следующим образом:

    dat[,combn(Categories,2),by=ID]

Однако остановка в этой точке сохранит столбец идентификатора и по умолчанию создаст столбец с именем V1, который в основномобъединяет массив, возвращаемый combn, в вектор категорий, а не в необходимую вам матрицу смежности из двух столбцов.Но, приковав к нему еще один вызов, вы можете легко создать матрицу, как если бы вы использовали любой отдельный вектор.В одной строке кода это будет выглядеть так:

    dat[,combn(Category,2),by=ID][,matrix(V1,ncol=2,byrow = T)]

Помните, что векторный столбец, который мы хотим преобразовать в матрицу, по умолчанию называется V1, а также мы хотим, чтобы матрица из 2 столбцов создавалась по строкевместо значения по умолчанию, которое по столбцу.Надеюсь, что это поможет, и дайте мне знать, если мне нужно что-то добавить к моему объяснению.Удачи!

0 голосов
/ 28 декабря 2018

Этот код будет работать

do.call(rbind,lapply(split(dat, dat$ID), function(x){
   t(combn(as.vector(x$Category), 2))
}))

Обновление

По предложению @Parfait, вы можете иметь на вместо split + lapply .

1) Используйте по для группировки узлов ("A", "B", "C" ...) по Категория ;

2) Используйте combn для создания ребра между узлами в каждой группе и t для преобразования матрицы для дальнейшего rbind

> edge.list <- by(dat, dat$ID, function(x) t(combn(as.vector(x$Category), 2)))

dat$ID: 1
     [,1] [,2]
[1,] "A"  "B" 
[2,] "A"  "C" 
[3,] "B"  "C" 
------------------------------------------------------------ 
dat$ID: 2
     [,1] [,2]
[1,] "B"  "E" 
[2,] "B"  "H" 
[3,] "E"  "H" 
------------------------------------------------------------ 
dat$ID: 3
     [,1] [,2]
[1,] "C"  "E" 

3) Затем объединить список

> do.call(rbind, edge.list)

    [,1] [,2]
[1,] "A"  "B" 
[2,] "A"  "C" 
[3,] "B"  "C" 
[4,] "B"  "E" 
[5,] "B"  "H" 
[6,] "E"  "H" 
[7,] "C"  "E"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...