为什么我在R中得到这个错误:“库(packlist[i])中的错误:'package'的长度必须为1”?

ki0zmccv  于 2023-09-27  发布在  其他
关注(0)|答案(2)|浏览(128)

我正在尝试编写一个函数,它将包名称作为参数,然后一次检查一个包是否已安装。如果它们没有安装,那么函数将安装这些包并随后将它们加载到当前会话中。如果它们已经安装,那么函数将只将包加载到当前会话中。

packin <- function(...) {
  packlist <- list(...)
  for(i in 1:length(packlist)) {
    if(!requireNamespace(packlist[i])) {
    install.packages(packlist[i])
    library(packlist[i])
      } else {
        library(packlist[i])
        }
  }
}

我尝试了两个包:tidyverse(已安装但未加载)和writexl(既未安装也未加载)。

packin('tidyverse', 'writexl')

但这会产生错误:Error in library(packlist[i]) : 'package' must be of length 1。但是,当我检查列表中一个项目的两个包的列表长度时,长度等于1。

packlist <- list('tidyverse', 'writexl')
length(packlist[1]) == 1

length(packlist[1]) == 1返回TRUE。那么,我做错了什么,或者没有理解'package'必须是长度1的错误,当它告诉我长度是1的时候?

9wbgstp7

9wbgstp71#

当向library()传递文字字符串以外的任何内容时,需要使用character.only = TRUE`:

p <- list("writexl", "tidyverse")
library(p[1])  ## Error in library(p) : there is no package called ‘p’
library(p[1], character.only = TRUE)

出现模糊错误消息的原因是library()在内部调用:

if (!character.only) package <- as.character(substitute(package))

在这种情况下,它的计算结果(奇怪地)为"[" "p" "1"(或者如果输入是packlist[i],则为"[" "packlist" "i"
你可以稍微更简洁地做到这一点:

packin <- function(...) {
  packlist <- unlist(list(...))
  ip <- rownames(installed.packages())
  to_install <- setdiff(packlist, ip)
  install.packages(to_install, character.only = TRUE)
  sapply(packlist, library, character.only = TRUE)
}

pacman包有很多有用的函数来处理这类事情。

hc8w905p

hc8w905p2#

下面的代码创建的函数解决了我的问题,感谢@BenBolker的回答:

packin <- function(...) {
  packs <- list(...)
  for(i in 1:length(packs)) {
    if(!requireNamespace(packs[[i]])) {
      install.packages(packs[[i]])
      library(packs[[i]], character.only = TRUE)
    } else {
    library(packs[[i]], character.only = TRUE)
    }
  }
}

相关问题