我继承了一些代码,我认为有空间进行整理,其中包括整理包游戏。
特别地,我希望看到加载的包的用途,以及(最重要的)是否有任何加载但未使用的包。
代码很长,包很多,所以我肯定更喜欢自动化这个过程。
作为一个小例子,如果我有:
packageload <- c("ggplot2", "readxl")
lapply(packageload, library, character.only = TRUE)
ggplot(diamonds, aes(x = cut)) +
geom_bar()
我想要一些输出告诉我ggplot()
是从ggplot2
中使用的(因此被用作包),并且readxl
目前未在项目代码中使用。
我一直在寻找一个明确的答案,最后,在@eh21指出的有用功能的基础上,我建立了这个小方法,它符合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 ----以上代码的一部分可以修改如下:
# Load packages ----
packageload <- search()
library(ggplot2)
library(readxl)
packageload <- search()[!(search() %in% packageload)] |> grep(pattern = "package:", value = TRUE) |> gsub(pattern = "package:", replacement = "")