Добавление элементов в список с помощью For L oop в R - PullRequest
2 голосов
/ 29 апреля 2020

Я пытаюсь создать простой фрейм данных, который содержит информацию о том, что авторы и их соответствующие документы. У меня есть матрица, которая содержит идентификаторы авторов в виде строк и идентификаторы бумаги в качестве столбцов. Эта матрица содержит 1 и 0, где 1 указывает, что автор работал над этим документом. Например, если A2P [1,1] == 1, это означает, что автор с идентификатором 1 работал над документом с идентификатором 1.

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

au_ID  P_ID
1      1
1      12        # Author 1 has worked on both paper 1 and 12
2      1         # Author 2 has also worked on paper 1, in addition to papers 2 and 3. 
2      2
2      3 
...

Вот что я делаю:

list1 <- list()
list2 <- list()
# Rows are Author IDs
# Columns are Paper IDs
for (row in 1:nrow(A2P)){
  for (col in 1:ncol(A2P)){
    if (A2P[row,col] == 1){
      list1 <- append(list1, row)
      list2 <- append(list2, col)
    }
  }
}
authorship["au_ID"] = list1
authorship["P_ID"] = list2

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

Любая помощь будет принята с благодарностью! Большое вам спасибо!

1 Ответ

3 голосов
/ 29 апреля 2020

Возможно, вам нужно which(A2P == 1L, arr.ind = TRUE)

mat <- matrix(c(1L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L), ncol = 3)

mat
#     [,1] [,2] [,3]
#[1,]    1    0    1
#[2,]    0    1    0
#[3,]    0    1    1

which(mat == 1L, arr.ind = TRUE)
#     row col
#[1,]   1   1
#[2,]   2   2
#[3,]   3   2
#[4,]   1   3
#[5,]   3   3

В этом случае row будет соответствовать au_ID, а col будет соответствовать P_ID. Затем, чтобы получить его в вашем формате полностью:

authorship <- which(mat == 1L, arr.ind = TRUE)
colnames(authorship) <- c('au_ID', 'P_ID')

as.data.frame(authorship)
##  au_ID P_ID
##1     1    1
##2     2    2
##3     3    2
##4     1    3
##5     3    3
...