2

考虑以下data.frame:

df <- structure(list(sufix = c("atizado", "atoria", "atório", "auta", 
                         "áutico", "ável"), min_stem_len = c(4, 5, 3, 5, 4, 2), replacement = c("", 
                                                                                                "", "", "", "", ""), exceptions = list(character(0), character(0), 
                                                                                                                                       character(0), character(0), character(0), c("afável", "razoável", 
                                                                                                                                                                                   "potável", "vulnerável"))), .Names = c("sufix", "min_stem_len", 
                                                                                                                                                                                                                          "replacement", "exceptions"), row.names = 21:26, class = c("tbl_df", 
                                                                                                                                                                                                                                                                                    "tbl", "data.frame"))

我在sufix这个 data.frame 的变量中有一个字符串列表。现在我有一个词word <- "amável",我想得到这个词的后缀,它的长度与df$sufix.

我正在使用以下代码:

library(stringr)
word <- "amável"
str_sub(word, start = -stringr::str_length(df$sufix))

但这会输出:

> str_sub(word, start = -stringr::str_length(df$sufix))
[1] "amável" "mável"  "mável"  "vel"    "mável"  "vel"   
> df$sufix
[1] "atizado" "atoria"  "atório"  "auta"    "áutico"  "ável"

我期待结果向量的最后一个元素是“ável”,因为:

> str_length("ável")
[1] 4
> str_sub(word, start = -4)
[1] "ável"

这是一个更简单的可重现示例:

set.seed(100)
a <- sample(1:10, 10000, replace = T)
res <- rep("ábc", 10000) %>% str_sub(start = -a)
sum(ifelse(a > 3, 3, a) != str_length(res))
[1] 2504
4

2 回答 2

1

如果您注意到,所有结果都是错误的(第一个除外)。

他们应该是

[1] "amável" "amável" "amável" "ável"   "amável" "ável" 

这可以通过以下方式轻松解决

library(stringi)
stri_sub(rep(word, 6), from = -stri_length(df$suffix))

我打赌你可以stringr同样重用你的代码。

### 编辑添加###

我现在明白你的意思了。绝对有一个奇怪的行为,很可能是特殊字符á。请参见下面的示例:

df <- data.frame(suffix = c("Lorem","ipsum","dolor","sit","amet","consectetur","adipiscing", "elit","Donec","arcu")) 
df$len <- stri_length(df$suffix)

然后查看结果的第 7 个元素中的奇怪行为:

stri_sub("amavel", from = -df$len)
##  [1] "mavel"  "mavel"  "mavel"  "vel"    "avel"   "amavel" "amavel" "avel"  
##  [9] "mavel"  "avel" 

# Compared to
stri_sub("amável", from = -df$len)
##  [1] "mável"  "mável"  "mável"  "vel"    "ável"   "amável" "mável"  "ável"  
##  [9] "mável"  "ável"

很奇怪,如果rep使用最后一种情况,结果会被纠正:

stri_sub(rep("amável", 10), from = -df$len)
## [1] "mável"  "mável"  "mável"  "vel"    "ável"   "amável" "amável" "ável"  
## [9] "mável"  "ável"

# note how the 7th element is now correct.

因此,即使它有点 hacky,上面提供的解决方案也应该可以工作

我尝试查看stri_sub它所指的 的代码C_stri_sub,但这对我来说是一条死胡同。也许更了解C和/或字符串操作的人可以来帮忙?

### 第二次编辑###

在我看来,问题在于stri_sub. 查看您在编辑中添加的替代代码:

set.seed(100)
a <- sample(1:10, 10000, replace = TRUE)
res <- stri_sub(rep("ábc", 10000), from = -a)
sum(ifelse(a > 3, 3, a) != stri_length(res))
## [1] 0
于 2016-08-29T19:57:08.927 回答
1

这已在 的开发分支中得到修复stringi,请参阅https://github.com/gagolews/stringi/issues/227str_sub来自stringr依赖stri_substringi)。一旦 CRAN 上有可用更新,“公众”中的任何人都可以复制正确的行为,而不是:

str_sub(word, start = -stringr::str_length(df$sufix))
## [1] "amável" "amável" "amável" "ável"   "amável" "ável"  
于 2017-03-21T14:01:22.083 回答