How can I extract the names of all package authors from CRAN
Asked Answered
A

2

13

To celebrate the 100,000th question in the tag, I'd like to create a list of the names of all package authors on CRAN.

Initially, I thought I could do this using available.packages() but sadly this doesn't contain a column of the authors.

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"   

This information is available in the DESCRIPTION file for each package. So I can think of two brute force ways, neither of which are very elegant:

  1. Download each of the 6,878 packages and read the DESCRIPTION file using base::read.dcf()

  2. Scrape each of the package pages on CRAN. For example, https://cran.r-project.org/web/packages/MASS/index.html tells me that Brian Ripley is the author of MASS.

I don't want to download all of CRAN to answer this question. And I don't want to scrape the HTML either, since the information in the DESCRIPTION file is a neatly formatted list of person objects (see ?person).

How can I use the information on CRAN to easily build a list of package authors?

Aureus answered 22/7, 2015 at 16:0 Comment(2)
Maybe use Gabor's API at r-pkg.org ?Trophoplasm
And the crandb package: github.com/metacran/crandbMetzgar
P
7

Taken from reverse_dependencies_with_maintainers, which was available at one point on the R developer site (I don't see it there now):

  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$"Authors@R")

Where Authors@R exists it might be parseable into something better using dget()

getAuthor <- function(x){
  if(is.na(x)) return(NA)
  a <- textConnection(x)
  on.exit(close(a))
  dget(a)
}
authors <- lapply(db$"Authors@R", 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
Picro answered 22/7, 2015 at 16:10 Comment(2)
Nice. I'll take a look. You can deparse Authors@R using dget(), the inverse operation of dput().Aureus
This is wonderful, thank you. I've added some additional code to show how to extract the Authors@RAureus
G
9

Why not use Gabor's API for CRAN packages?

e.g. 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]"
Gibbeon answered 22/7, 2015 at 16:4 Comment(0)
P
7

Taken from reverse_dependencies_with_maintainers, which was available at one point on the R developer site (I don't see it there now):

  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$"Authors@R")

Where Authors@R exists it might be parseable into something better using dget()

getAuthor <- function(x){
  if(is.na(x)) return(NA)
  a <- textConnection(x)
  on.exit(close(a))
  dget(a)
}
authors <- lapply(db$"Authors@R", 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
Picro answered 22/7, 2015 at 16:10 Comment(2)
Nice. I'll take a look. You can deparse Authors@R using dget(), the inverse operation of dput().Aureus
This is wonderful, thank you. I've added some additional code to show how to extract the Authors@RAureus

© 2022 - 2024 — McMap. All rights reserved.