Как я могу извлечь имена всех авторов пакета из CRAN

Чтобы отметить 100 000-й вопрос в теге r, я бы хотел создать список имен всех авторов пакета на CRAN.

Первоначально я думал, что смогу сделать это с помощью available.packages(), но, к сожалению, это не содержит столбца авторов.

pdb <- available.packages()
colnames(pdb)

 [1] "Package"               "Version"               "Priority"             
 [4] "Depends"               "Imports"               "LinkingTo"            
 [7] "Suggests"              "Enhances"              "License"              
[10] "License_is_FOSS"       "License_restricts_use" "OS_type"              
[13] "Archs"                 "MD5sum"                "NeedsCompilation"     
[16] "File"                  "Repository"   

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

  • Загрузите каждый из 6,878 пакетов и прочитайте файл DESCRIPTION, используя base::read.dcf()

  • Очистите каждую страницу пакета на CRAN. Например, https://cran.r-project.org/web/packages/MASS/index.html сообщает мне, что Брайан Рипли является автором МАССЫ.

Я не хочу загружать весь CRAN, чтобы ответить на этот вопрос. И я также не хочу очищать HTML, поскольку информация в файле DESCRIPTION является аккуратно отформатированным списком объектов person (см. ?person).

Как я могу использовать информацию о CRAN для простой сборки списка авторов пакетов?

Ответ 1

Взято из reverse_dependencies_with_maintainers, которое было доступно в какой-то момент на сайте R developerWorks (теперь я его не вижу):

  description <- sprintf("%s/web/packages/packages.rds",
                          getOption("repos")["CRAN"])
  con <- if(substring(description, 1L, 7L) == "file://") {
       file(description, "rb")
  } else {
      url(description, "rb")
  }
  db <- as.data.frame(readRDS(gzcon(con)),stringsAsFactors=FALSE)
  close(con)
  rownames(db) <- NULL

  head(db$Author)
  head(db$"[email protected]")

Где [email protected] существует, он может обрабатываться в чем-то лучше, используя dget()

getAuthor <- function(x){
  if(is.na(x)) return(NA)
  a <- textConnection(x)
  on.exit(close(a))
  dget(a)
}
authors <- lapply(db$"[email protected]", getAuthor)
head(authors)

[[1]]
[1] NA

[[2]]
[1] "Gaurav Sood <[email protected]> [aut, cre]"

[[3]]
[1] "Csillery Katalin <[email protected]> [aut]"
[2] "Lemaire Louisiane [aut]"                         
[3] "Francois Olivier [aut]"                          
[4] "Blum Michael <[email protected]> [aut, cre]"  

[[4]]
[1] NA

[[5]]
[1] "Csillery Katalin <[email protected]> [aut]"
[2] "Lemaire Louisiane [aut]"                         
[3] "Francois Olivier [aut]"                          
[4] "Blum Michael <[email protected]> [aut, cre]"  

[[6]]
[1] NA

Ответ 2

Почему бы не использовать Gabor API для пакетов CRAN?

например. http://crandb.r-pkg.org/MASS

library("httr")
content(GET("http://crandb.r-pkg.org/MASS"))$Author
[1] "Brian Ripley [aut, cre, cph],\nBill Venables [ctb],\nDouglas M. Bates [ctb],\nKurt Hornik [trl] (partial port ca 1998),\nAlbrecht Gebhardt [trl] (partial port ca 1998),\nDavid Firth [ctb]"