gpt4 book ai didi

r - 为什么 base::detach 以它的方式验证名称输入?

转载 作者:行者123 更新时间:2023-12-01 13:57:55 26 4
gpt4 key购买 nike

在通过 Detach several packages at once 工作之后, 我现在想知道 base::detach 中的以下验证代码是这样的原因,还是存在错误?

(函数本身是 detach(name, pos = 2L, unload = FALSE, character.only = FALSE,
力=假)
)

if (!missing(name)) {
if (!character.only)
name <- substitute(name)
pos <- if (is.numeric(name))
name
else {
if (!is.character(name))
name <- deparse(name)
match(name, search())
}
if (is.na(pos))
stop("invalid 'name' argument")

在我看来,无论是否设置了“character.only”参数,在冒险运行 substitute( )name 值上。文档没有明确说明当 name 是字符串时,您必须设置 character.only=TRUE
因此,在我开始提交错误/增强请求之前,是否有充分的理由证明验证是这样的?

编辑:评论 mnel 的响应,这是我的测试示例。

Rgames> detlist<-c('Hmisc','survival','splines')
Rgames> library(Hmisc)
Rgames> debug(base::detach)
Rgames> base::detach(detlist[1])

# skipped the startup stuff.

Browse[2]>
debug: if (!character.only) name <- substitute(name)
Browse[2]> name
[1] "Hmisc"
Browse[2]>
debug: name <- substitute(name)
Browse[2]>
debug: pos <- if (is.numeric(name)) name else {
if (!is.character(name))
name <- deparse(name)
match(name, search())
}
Browse[2]> name
detlist[1]
Browse[2]>
debug: if (!is.character(name)) name <- deparse(name)
Browse[2]>
debug: name <- deparse(name)
Browse[2]> deparse(name)
[1] "detlist[1]"

所以你看到了问题。我的输入变量是一个有效的名称,但未能将 character.only 设置为 TRUE 导致发生不需要的 deparse,并且 match(name, search()) 由于显而易见的原因而失败。
在我看来,如果首先检查 is.character 对用户来说会更容易,尽管在 tryCatch 中处理 mnel 描述的情况。两个原因:1) 如果 detach 甚至不需要 character.only 参数,它会更“用户友好”,以及 2) 目前的文档没有警告当 name 参数是一个包含字符串的对象时,用户必须设置character.only==TRUE(但不是,我相信如果它是一个普通的字符串。分离(package:Hmisc) 或分离("package:Hmisc") 工作,但正如我的示例所示,不是对同一字符串的引用)。

最佳答案

这是一个不冒险评估 name 的问题参数,除非你知道它只是字符。

请注意 help('detach')描述了 name参数为

This can be an unquoted name or a character string but not a character vector. If a number is supplied this is taken as pos.

is.character将评估其参数,而 substitute 则不会。如果name不是字符串,它将是不带引号的字符串(例如 package:stats)。如果你要测试 is.character(x = package:stats) ,这将尝试评估 package:stats (即调用 `:`(package,stats)。这不会很好(并且会返回错误或无意义的东西,具体取决于您的搜索路径上是否有 packagestats 的值)。

使用 character.only , 表示 substitute将被调用(不会评估参数),但会返回 language 的对象类型(如果原始名称是不带引号的名称)或字符串(如果它最初是字符串)。不管结果如何,name可以是deparsed创建所需的字符串。

您可以通过创建一个适当调用 browser 的函数来跟踪正在发生的事情。

例如

d <- function (name, pos = 2L, unload = FALSE, character.only = FALSE, 
force = FALSE) {

if (!missing(name)) {
browser()
if (!character.only)
name <- substitute(name)
pos <- if (is.numeric(name))
name
else {
if (!is.character(name))
name <- deparse(name)
match(name, search())
}
if (is.na(pos))
stop("invalid 'name' argument")

}
return(list(name, pos))
}

# called using an unquoted string.

d(package:stats, pos = 2L)
# Called from: d(package:stats, pos = 2L)
# Browse[1]> n
# debug at #7: if (!character.only) name <- substitute(name)
# Browse[2]> str(name)
# Error in str(name) : object 'package' not found
# Browse[2]> n
# debug at #7: name <- substitute(name)
# Browse[2]> n
# debug at #9: pos <- if (is.numeric(name)) name else {
# if (!is.character(name))
# name <- deparse(name)
# match(name, search())
# }
# Browse[2]> str(name)
# language package:stats
# Browse[2]> n
# debug at #12: if (!is.character(name)) name <- deparse(name)
# Browse[2]> n
# debug at #12: name <- deparse(name)
# Browse[2]> n
# debug at #14: match(name, search())
# Browse[2]> n
# debug at #16: if (is.na(pos)) stop("invalid 'name' argument")
# Browse[2]> n
# debug at #16: NULL
# Browse[2]> str(name)
# chr "package:stats
# Browse[2]> Q

d('package:stats', pos = 2L)
# Called from: d("package:stats", pos = 2L)
# Browse[1]> n
# debug at #7: if (!character.only) name <- substitute(name)
# Browse[2]> n
# debug at #7: name <- substitute(name)
# Browse[2]> n
# debug at #9: pos <- if (is.numeric(name)) name else {
# if (!is.character(name))
# name <- deparse(name)
# match(name, search())
# }
# Browse[2]> str(name)
# chr "package:stats"
# Browse[2]> Q

根据已编辑的问题进行编辑。

也许是路name帮助文件中的描述应该与'package in的定义一致需要 &图书馆 (which have similar methods of dealing with姓名and character.string` 样式参数

the name of a package, given as a name or literal character string, or a character string, depending on whether character.only is FALSE (default) or TRUE).

help('detach') 中的当前定义使用 character string暗示包含您希望搜索路径上的项目名称的文字字符串 detachcharacter vector定义一个字符向量,其中包含一个字符串,该字符串是您希望搜索路径上的项目的名称 detach .

我更改了 help('detach') 中的定义到

This can be an unquoted name or a literal character string. If character.only == TRUE then a character vector of length 1 may be supplied. If a number is supplied this is taken as pos.

或类似内容可能会有帮助。

关于r - 为什么 base::detach 以它的方式验证名称输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17554597/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com