преобразовать список смежности, разделенный запятыми, в список из 2 столбцов (для создания объекта igraph)

Я много искал в огромном количестве информации stackoverflow, чтобы найти решение, но я застрял! Я изучаю R и igraph, читая и делая, поэтому, пожалуйста, потерпите меня, если вопрос слишком простой :)

Я использовал этот приведенный ниже код для извлечения текстовых данных (список смежности) соавторства со страниц профиля ученого Google, и я хотел превратить его в сети соавторства, но мне не удалось использовать graph_from_adjlist в Igraph; сеть строилась неправильно, поэтому я изменил свой подход и попытался сначала превратить их в edgelist, а затем использовать более распространенную функцию graph_from_edgelist, я нашел решение здесь; он отлично работает, когда количество строк (в моем случае публикаций) меньше 300, но для большего количества он дает эту ошибку в R:

Error in rep(x[1], length(x) - 1) : invalid 'times' argument
Called from: FUN(X[[i]], ...)
Browse[1]> Q

Честно говоря, я не знаю логики кода превращения столбцов списка смежности в 2-столбцовый edgelist, и мне не удалось выяснить, что не так.

Вот мой небольшой фрагмент кода (я описал каждый шаг во встроенных комментариях):

library(scholar)
library(igraph) 
# one scholar profile link (works fine with small number of authors)
scurl <- "https://scholar.google.com/citations?user=nG42BMAAAAAJ&hl=en"
# prof Welman google scholar link as an example that gives the above error
# scurl <- "https://scholar.google.com/citations?user=_q2NODAAAAAJ&hl=en"
citid <- strsplit((strsplit(scurl,"&",fixed = TRUE)[[1]][1]),"=",fixed = TRUE)[[1]][2]
# authors <- as.data.frame(cSplit(subset(get_publications(citid,flush = TRUE),select = "author"),splitCols = "author",sep = ",")) ## this I put to check if authors are extracting in a right way
pub <- get_publications(citid,flush = TRUE)
coauthors <- as.character(tolower(pub$author)) ##to make text differences less effective in result
adjlist=strsplit(coauthors,",") # splits the character strings into list with different vector for each line
col1 <- unlist(lapply(adjlist,function(x) rep(x[1],length(x)-1))) # establish first column of edgelist by replicating the 1st element (=ID number) by the length of the line minus 1 (itself)
col2 <- unlist(lapply(adjlist,"[",-1)) # the second line I actually don't fully understand this command, but it takes the rest of the ID numbers in the character string and transposes it to list vertically
edgelist <- cbind(col1,col2) # creates the edgelist by combining column 1 and 2.
coauthorgraph <- graph_from_edgelist(edgelist,directed = FALSE)
set.seed(333)
coauthorgraph$layout <- layout.circle
tkplot(coauthorgraph)

Я попытался добавить условие (раз = 400) в строку col2, но это не помогло. Буду очень благодарен за любой совет.


person Ali    schedule 09.01.2016    source источник


Ответы (1)


Один столбец - это каждый элемент за вычетом первого, другой столбец - это первый элемент, повторяющий длину вектора - 1. Вы можете получить это с помощью rep(..., times=lengths(adjlist)) - 1L. Итак, собравшись после того, как вы получите pub,

## tolower does character conversion, and remove the trailing "..."
coauthors <- sub('[ ,.]+$', '', tolower(pub$author))

## Make edgelist by repeating 1st elements each length(vector)-1L
adjlist <- strsplit(coauthors, '\\s*,\\s*')
edgelist <- cbind(
    unlist(lapply(adjlist, tail, -1L)),                        # col1
    rep(sapply(adjlist, `[`, 1L), times=lengths(adjlist)-1L)   # col2
)

## make graph
g <- graph_from_edgelist(edgelist, directed=FALSE)

## Offset labels a bit: nodes printed from +x-axis counter-clockwise
ord <- V(g)                                               # node order
theta <- seq(0, 2*pi-2*pi/length(ord), 2*pi/length(ord))  # angle
theta[theta>pi] <- -(2*pi - theta[theta>pi])              # convert to [0, pi]
dists <- rep(c(1, 0.7), length.out=length(ord))           # alternate distance

## Plot
plot(g, layout=layout.circle, vertex.label.degree=-theta, 
     vertex.label.dist=dists, vertex.label.cex=1.1,
     vertex.size=14, vertex.color='#FFFFCC', edge.color='#E25822')

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

Обновлять

Эта ошибка возникает из-за попытки указать отрицательный аргумент times (т.е. когда один из элементов в вашем списке не содержит авторов).

Чтобы добавить самостоятельные циклы и удалить записи с нулевым символом, которые встречаются в новом запросе, вам нужно сначала отфильтровать список соавторов, чтобы он содержал только записи с символами, а затем повторить те элементы, которые имеют длину == 1 в списке прил. В остальном должно быть так же.

scurl <- "scholar.google.com/citations?user=xqefLxQAAAAJ&hl=en"
citid <- regmatches(scurl, gregexpr('(?<=user=)[[:alnum:]]+', scurl, perl=TRUE))
pub <- get_publications(citid, flush=TRUE)

## tolower does character conversion, and remove the trailing "..."
coauthors <- sub('[ ,.]+$', '', tolower(pub$author))
coauthors <- coauthors[nzchar(coauthors)]  # only keep entries that aren't blank

## Add self-loops for single-author entries
adjlist <- strsplit(coauthors, '\\s*,\\s*')
lens <- lengths(adjlist)
adjlist[lens==1L] <- lapply(adjlist[lens==1L], rep, times=2)  # repeat single author entries

Затем продолжайте, как раньше.

person Rorschach    schedule 10.01.2016
comment
Спасибо за ваш ответ, но та же проблема возникает снова, он отлично работает с небольшим количеством публикаций (например, с профилем ученого Google, который вы использовали), например, если вы используете эти два профиля с большим количеством публикаций (# prof snijders scurl ‹- scholar.google.com/citations?user=xqefLxQAAAAJ&hl=en # prof Welman google scholar link в качестве примера, который дает указанную выше ошибку scurl ‹- scholar.google. com / citations? user = _q2NODAAAAAJ & hl = en), то снова возникает ошибка: Ошибка в rep (sapply (adjlist, [, 1L), times = lengths (adjlist) - 1L): недопустимый аргумент 'times' - person Ali; 10.01.2016
comment
и можно ли не удалять статьи одного автора (одного автора)? скопировать его в оба столбца и получить петлю на графике? таким образом можно сравнить их с количеством статей нескольких авторов и дать некоторое представление ... кстати, я собираюсь опубликовать его как блестящее приложение в ближайшее время, но я не могу установить пакеты dyplr и scholar на свой экземпляр Amazon из-за мало оперативной памяти (1 ГБ). - person Ali; 10.01.2016
comment
Я забыл упомянуть ваше имя в двух комментариях выше. Буду благодарен услышать вашу идею как ее решить @slickrickulicious - person Ali; 10.01.2016
comment
спасибо за ваше обновление, теперь он работает как шарм, но есть небольшая проблема в вашем методе извлечения идентификатора ученого Google из URL-адреса, вы должны удалить часть после & (включая ее также), я использовал для этого эту строку: citid ‹- strsplit ((strsplit (scurl, &, fixed = TRUE) [[1]] [1]), =, fixed = TRUE) [[1]] [2] Еще раз спасибо за вашу большую помощь, теперь, похоже, работают самостоятельные циклы и пустые поля автора :) @slickrickulicious - person Ali; 10.01.2016
comment
работая с теми же данными, что и в этом вопросе (который я задавал ранее), у меня проблема с некоторыми именами авторов с разными инициалами, это означает, что в случае некоторых авторов в Google Scholar существует более одного написания для одного и того же человека, например sm iacus и s iacus, которые являются одним и тем же человеком, любая идея, как я могу найти, что они такие же, и заменить одно другим (вероятно, с наиболее популярным написанием имени)? это приводит к тому, что в результирующей сети будет 2 узла для одного и того же человека :( - person Ali; 25.03.2016