[This article was first published on R | Discindo, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.I am involved in a Posit Teamdeployment, and one of the things that we are looking into is default R packagesthat should be made available to all users. We are looking to do this because wewould like to avoid people installing, for example tidyverse, in their own locallibraries in order to save on space and to make sure everyone is on the sameversion, at least for the packages that are considered to be a preferreddefault option for working with data in R.
In order to do this we wanted to collect all the packages that are currentlyused, their versions, source repository and similar information. That way wecan see if anything else should be installed for all users, in addition to thebest guess that we should have tidyverse, tidymodels, and shiny.
In order to do this we first have to get the list of installed packages, whichis fairly simple to do:
installed\_packages <- installed.packages()
Then, utils::packageDescription can be used to get the packagesdescriptions. For example for getting the package description fordplyr` we can run:
dplyr\_pkg\_desc <- utils::packageDescription('dplyr')
The result is a list, and it can be subsetted to see details, for example:
```
dplyr_pkg_desc[1]$Type[1] "Package"> dplyr_pkg_desc[2]$Package[1] "dplyr"> dplyr_pkg_desc[3]$Title[1] "A Grammar of Data Manipulation"> dplyr_pkg_desc[4]$Version[1] "1.1.4"
`` At this point, I am thinking that all these description files have the samestructure. Therefore, if I want to get all packages’ version I need tolapplytoget the fourth element and that’s that. It turns out this is not entirely true.Not all packages have the same structure of the description. Seetydir`:
```
tidyr_pkg_desc[1]$Package[1] "tidyr"> tidyr_pkg_desc[2]$Title[1] "Tidy Messy Data"> tidyr_pkg_desc[3]$Version[1] "1.3.1"> tidyr_pkg_desc[4]$
Authors@R[1] "c(\n person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")),\n person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = \"aut\"),\n person(\"Maximilian\", \"Girlich\", role = \"aut\"),\n person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"ctb\"),\n person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"))\n )"`` Number four is the authors, and version is three. And these are two packages thatare ultimately from the same author. Look atdata.table`:
```
data.table_pkg_desc[1]$Package[1] "data.table"> data.table_pkg_desc[2]$Version[1] "1.15.4"> data.table_pkg_desc[3]$Title[1] "Extension of
data.frame"> data.table_pkg_desc[4]$Depends[1] "R (>= 3.1.0)" ``` Now, of course, subsetting works with using the name, instead of the position:
```
dplyr_pkg_desc[["Version"]][1] "1.1.4"> tidyr_pkg_desc[["Version"]][1] "1.3.1"> data.table_pkg_desc[["Version"]][1] "1.15.4" ``` However, to be honest, it rarely comes to my mind to subset lists like this.
package\_names <- installed.packages()[, 1]all\_packages\_data <- lapply(package\_names, utils::packageDescription)version\_number <-lapply(1:length(package\_names), function (x) {all\_packages\_data[[x]][["Version"]]})
The above is possible, and then to cbind all needed fields in a data.frame.
However, looking at the packageDescription documentation, it seems the best wayis to use additional arguments the function. This is neat:
package\_data <- lapply(package\_names,utils::packageDescription,fields = c("Package", "Version", "Built", "Repository"))
And then there is another surprise. The results are with classpackageDescription which makes getting to a data.frame, or tibble inthis case, a bit complicated:
package\_data <- purrr::map\_df(package\_names,utils::packageDescription,fields = c("Package", "Version", "Built", "Repository"))Error in `as\_tibble()`:! All columns in a tibble must be vectors.✖ Column `askpass` is a `packageDescription` object.
The full solution involves a step of changing the class of the object usingas, and then reassigning the names of each element, because the previous stepremoves them:
package\_data <- lapply(package\_names,utils::packageDescription,fields = c("Package", "Version", "Built", "Repository")) |>lapply(as, Class = "list") |>lapply(setNames, c("Package", "Version", "Built", "Repository")) |>dplyr::bind\_rows()
To leave a comment for the author, please follow the link and comment on their blog: R | Discindo.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.Continue reading: Few notes on getting R package data from the local library