试试这个:
require(stringr)
x <- c("A'B'C","E!FG@H","I$JKL&M")
substr(x,2,2) <- ":"
str_sub(x, rep(-2, length(x)), rep(-2, length(x))) <- ":"
它表现得像这样的原因是因为通过 str_cstr_sub<-
传递了结果,这对你来说是崩溃的地方。str_sub(x, start, end)
源代码中的函数是:
"str_sub<-" <- function(string, start = 1L, end = -1L, value) {
str_c(
str_sub(string, end = start - 1L),
value,
ifelse(end == -1L, "", str_sub(string, start = end + 1L)))
}
因此,我们有效地将三个参数传递给str_c
函数,一个或多个字符向量、一个插入字符串和一个折叠参数(ifelse 位)。如果str_sub
不使用赋值函数运行的结果是(如果我们已经运行了第一个str_sub:
> (test.string <- str_sub(x, start = 1L, end = -2 - 1L)) #start defaults to 1L
[1] "A:B" "E:FG" "I:JKL"
> replace.string <- ":"
> (collapse.string <- ifelse(end == -1L, "", str_sub(string, start = end + 1L)))
[1] "C"
> str_c(test.string, replace.string, collapse.string)
[1] "A:B:C" "E:FG:C" "I:JKL:C"
因此,首先我们将所有内容保存到要替换的符号左侧,然后设置折叠参数。折叠参数有点有趣,如果你查看 str_c 的文档,你会发现它说
如果 collapse 是...非'NULL',则在每行的末尾插入该字符串,并且整个矩阵折叠为单个字符串。
所以这正是这里发生的事情,当我们替换我们的字符串时,它会将折叠参数添加到我们每个字符串的末尾。
但实际上,如果不使用 ifelse 函数,这将起作用,因为没有 ifelse,str_sub(string, start = end + 1L)
将返回[1] "C" "H" "M"
而不是仅获取第一个索引“C”。
所以这就是为什么当我们添加 c(-2, -2, -2) 的开始和结束值时,我们可以得到正确的答案:
> (test.string <- str_sub(x, start = 1L, end = c(-2, -2, -2) - 1L)) #start defaults to 1L
[1] "A:B" "E:FG" "I:JKL"
> replace.string <- ":"
> (collapse.string <- ifelse(end == -1L, "", str_sub(string, start = c(-2, -2, -2) + 1L)))
[1] "C" "H" "M"
> str_c(test.string, replace.string, collapse.string)
[1] "A:B:C" "E:FG:C" "I:JKL:C"