2016-08-29 10 views
2

Рассмотрим на следующие data.frame:stringr :: str_sub выход неожиданно

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", и я хочу получить sufix этого слова той же длины, что и каждое слово 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" 

Я ожидал, что последний элемент результирующего вектора быть «Авель», так как:

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

Здесь мор e простой воспроизводимый пример:

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 
+1

поднял вопрос к STRINGI-х GitHub страницы: https://github.com/gagolews/ stringi/issues/227 – PavoDive

ответ

1

Это было исправлено в отрасли разработки stringi см https://github.com/gagolews/stringi/issues/227 (как str_sub из stringr полагается на stri_sub в stringi). После того, как обновление доступно на CRAN, правильное поведение должно быть воспроизводимы любым из «широкой публики», чем:

str_sub(word, start = -stringr::str_length(df$sufix)) 
## [1] "amável" "amável" "amável" "ável" "amável" "ável" 
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 и/или строковых манипуляциях может прийти и протянуть руку?

### ВТОРОЙ EDIT ###

Мне кажется, проблема с повторением строки внутри вызова 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 
+0

Я не думаю, что это решит проблему. Я добавлю более простой воспроизводимый пример. –

+0

Каков ваш ожидаемый результат? Мой код создает результат, который я вставил поверх ответа, который я бы ожидал. – PavoDive

+0

Я знаю, что он решил. Посмотрите на простой новый пример. Ваше решение не работает для больших векторов. Нет никакого смысла в том, что ваше решение также работает, поскольку в документации stringr говорится, что он перерабатывает все аргументы на длину самого длинного. –