我正在尝试将字符串转换为数字,并遇到了一些意外的行为str_replace.这是一个最小的工作示例:
library(stringr)
x <- c("0", "NULL", "0")
# This works, i.e. 0 NA 0
as.numeric(str_replace(x, "NULL", ""))
# This doesn't, i.e. NA NA NA
as.numeric(str_replace(x, "NULL", NA))
Run Code Online (Sandbox Code Playgroud)
在我看来,第二个例子应该工作,因为它应该只替换向量中的第二个条目NA(它是字符向量中的有效值).但事实并非如此:内部str_replace将所有三个条目转换为NA.
这里发生了什么?我查看了文档str_replace,stri_replace_all但没有看到明显的解释.
编辑:为了澄清,这是stringr_1.0.0和stringi_1.0-1R上3.1.3,Windows 7操作系统.
这是包中的一个错误stringi,但现在已修复(回想一下,这stringr是基于stringi- 前者也将受到影响)。
通过最新的开发版本,我们得到:
stri_replace_all_fixed(c("1", "NULL"), "NULL", NA)
## [1] "1" NA
Run Code Online (Sandbox Code Playgroud)
看一下 的源代码str_replace。
function (string, pattern, replacement)
{
replacement <- fix_replacement(replacement)
switch(type(pattern), empty = , bound = stop("Not implemented",
call. = FALSE), fixed = stri_replace_first_fixed(string,
pattern, replacement, opts_fixed = attr(pattern, "options")),
coll = stri_replace_first_coll(string, pattern, replacement,
opts_collator = attr(pattern, "options")), regex = stri_replace_first_regex(string,
pattern, replacement, opts_regex = attr(pattern,
"options")), )
}
<environment: namespace:stringr>
Run Code Online (Sandbox Code Playgroud)
这导致了 find fix_replacement,它位于Github,我也将其放在下面。如果您在主环境中运行它,您会发现fix_replacement(NA)返回NA. 您可以看到它依赖于stri_replace_all_regex来自stringi包的 。
fix_replacement <- function(x) {
stri_replace_all_regex(
stri_replace_all_fixed(x, "$", "\\$"),
"(?<!\\\\)\\\\(\\d)",
"\\$$1")
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,当使用您的参数(您的 、 和 )运行时,和stri_replace_first_fixed都会stri_replace_first_regex返回。问题在于和是 C++ 代码,因此弄清楚发生了什么变得有点棘手。c(NA,NA,NA)stringpatternreplacementstri_replace_first_fixedstri_replace_first_regex
stri_replace_first_fixed可以在这里找到。
stri_replace_first_regex可以在这里找到。
据我在有限的时间和我相对生疏的 C++ 知识下所能辨别的,该stri__replace_allfirstlast_fixed函数replacement使用stri_prepare_arg_string. 根据文档,如果遇到 NA,它将抛出错误。我没有时间完全追踪它,但我怀疑这个错误可能导致所有 NA 的奇怪返回。