0

我正在尝试替换字符串向量的所有元素中的字符,其中字符不同,但始终与字符串的开头或结尾有一定距离。我可以substr成功地使用替换字符串开头的字符。我试图str_sub从包中使用stringr来替换字符串末尾的字符(因为它允许用负数倒数)。它替换了字符,但对于第一个元素之后的所有元素,它将字符右侧的所有内容替换为第一个元素的字符串末尾:

> require(stringr)
> x <- c("A'B'C","E!FG@H","I$JKL&M")
> substr(x,2,2) <- ":"
> x
[1] "A:B'C"   "E:FG@H"  "I:JKL&M"
> str_sub(x,-2,-2) <- ":"
> x
[1] "A:B:C"   "E:FG:C"  "I:JKL:C"
4

2 回答 2

6

试试这个:

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"
于 2012-11-02T18:30:35.247 回答
1

不知道问题出在哪里str_sub,但你可以自己动手:

my_sub <- function(x,n,s) {
  N <- nchar(x)-n+1
  substr(x,n,n) <- substr(x,N,N) <- s
  x 
}
my_sub(x,2,":")
# [1] "A:B:C"   "E:FG:H"  "I:JKL:M"
于 2012-11-02T18:25:10.403 回答