2015-12-17 4 views
9

Я пытаюсь преобразовать символьную строку в числовую и столкнулся с каким-то неожиданным поведением с str_replace. Вот минимальный рабочий пример:Неожиданное поведение с str_replace «NA»

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)) 

На мой взгляд, второй пример должен работать как следует только заменить второй элемент в векторе с NA (который является допустимым значением в векторе символов). Но это не так: внутренний str_replace преобразует все три записи в NA.

Что здесь происходит? Я просмотрел документацию для str_replace и stri_replace_all, но не вижу очевидного объяснения.

EDIT: Чтобы уточнить, это с stringr_1.0.0 и stringi_1.0-1 на R 3.1.3, Windows 7.

+1

Конечно неожиданное поведение в исходном коде, который нуждается в коррекции, вам необходимо предоставить Н.А. строку, чтобы она работает: 'as.numeric (str_replace (x, "NULL", "NA")) ' –

+0

Возможное обходное решение? 'x <- c (" 0 "," NULL "," 0 "); y <- x; y [y == "NULL"] <- NA; as.numeric (y) ' – bubble

+1

Мне что-то не хватает, второй пример работает для меня' as.numeric (str_replace (x, "NULL", NA)) [1] 0 NA 0' –

ответ

3

Посмотрите на исходный код 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> 

Это приводит к нахождению 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") 
} 

Интересно то, что stri_replace_first_fixed и stri_replace_first_regex возвращают c(NA,NA,NA) при запуске с параметрами (ваш string, pattern и replacement). Проблема в том, что stri_replace_first_fixed и stri_replace_first_regex являются кодом на C++, поэтому становится немного сложнее выяснить, что происходит.

stri_replace_first_fixed можно найти here.

stri_replace_first_regex можно найти here.

Насколько я могу различить с ограниченным временем и моим относительно ржавым знанием С ++, функция stri__replace_allfirstlast_fixed проверяет аргумент replacement, используя stri_prepare_arg_string. Согласно documentation для этого, он выдает ошибку, если встречается с NA. У меня нет времени полностью отслеживать это за пределами этого, но я подозреваю, что эта ошибка может вызвать нечетное возвращение всех НС.

3

Это была ошибка в stringi пакете, но теперь это fixed (напомним, что stringr основан на stringi - бывший должны быть затронуты тоже).

С самой последней версией развития мы получаем:

stri_replace_all_fixed(c("1", "NULL"), "NULL", NA) 
## [1] "1" NA 
+0

Я все еще получаю эту проблему, используя stringr 1_2_0, которая вызывает stringi_1 .1.5? Хотя видно, что проблема была закрыта, хотя на github, https://github.com/tidyverse/stringr/issues/110 Любая идея, что происходит? Благодаря! – Matifou

Смежные вопросы