如何查看 R 脚本中使用的包是什么,以及当前未使用哪些包?

How can I see what are packages being used for in an R script, and which packages are currently not used?

我继承了一些代码,我认为还有整理空间,包括整理游戏包。

特别是,我既要查看已加载包的用途,又要查看(最重要的)是否有任何已加载但未使用的包。

代码很长,包也很多,所以我当然更愿意自动化这个过程。

举个小例子,如果我有:

packageload <- c("ggplot2", "readxl")
lapply(packageload, library, character.only = TRUE)

ggplot(diamonds, aes(x = cut)) +
  geom_bar()

我想要一些输出告诉我 ggplot()ggplot2 中使用(因此被用作包),并且 readxl 当前未在项目中使用代码。

我一直在寻找一个明确的答案,最后,在 @eh21 here 指出的有用功能的基础上,我用 3 行代码构建了这个符合意图的小方法,并且任何人(我指的是像我这样没有经验的程序)都可以毫不费力地复制他们的案例。

原理是在包加载完成后,在实际项目代码之前使用这种方法(即不需要运行来获取所需信息),如下:

# Load packages ----

packageload <- c("ggplot2", "readxl")
lapply(packageload, library, character.only = TRUE)


# Find which packages do used functions belong to ----

used.functions <- NCmisc::list.functions.in.file(filename = "thisfile.R", alphabetic = FALSE) |> print()


# Find which loaded packages are not used ----

used.packages <- used.functions |> names() |> grep(pattern = "packages:", value = TRUE) |> gsub(pattern = "package:", replacement = "") |> print()

unused.packages <- packageload[!(packageload %in% used.packages)] |> print()


# Actual project code (no need to be run) ----

ggplot(diamonds, aes(x = cut)) +
  geom_bar()

相关输出为:

> used.packages
[1] "base"    "ggplot2"

> used.functions
$`character(0)`
[1] "list.functions.in.file"

$`package:base`
[1] "c"      "lapply" "print"  "names"  "grep"   "gsub"   

$`package:ggplot2`
[1] "ggplot"   "aes"      "geom_bar"

> unused.packages
[1] "readxl"

备注:

  • 这需要 install.packages("NCmisc"),但是为了保持一致性我没有加载那个包(而是使用 ::),因为它不应该出现在 used.packages;
  • 如果使用 RStudio 并想将其应用于多个脚本,在 NCmisc::list.functions.in.file 中使用 rstudioapi::getSourceEditorContext()$path 而不是 "thisfile.R" 会很方便。
  • 上述方法适用于 lapply() 用于命名对象以加载包的情况。如果不求助于命名对象(例如使用一系列 library()require())而不是加载包,则 # Load packages ----[=上面39=]段代码可以修改如下:
# Load packages ----

packageload <- search()

library(ggplot2)
library(readxl)

packageload <- search()[!(search() %in% packageload)] |> grep(pattern = "package:", value = TRUE) |> gsub(pattern = "package:", replacement = "")