2015-12-17 18 views
9

Próbuję przekonwertować ciąg znaków na numeryczny i napotkałem pewne nieoczekiwane zachowanie z str_replace. Oto przykład minimum pracy:Nieoczekiwane zachowanie z 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)) 

Moim zdaniem, drugi przykład powinien działać jak należy zastąpić tylko drugi wpis w wektorze z NA (która jest ważna wartość w postaci wektorowej). Ale tak nie jest: wewnętrzna str_replace konwertuje wszystkie trzy wpisy na NA.

Co tu się dzieje? Przejrzałem dokumentację dla str_replace i stri_replace_all, ale nie widzę oczywistego wyjaśnienia.

EDIT: W celu wyjaśnienia, to jest z stringr_1.0.0 i stringi_1.0-1 na badania 3.1.3, Windows 7.

+1

pewnością nieoczekiwane zachowanie w kodzie źródłowym, która wymaga korekty, trzeba zapewnić NA ciąg, aby to działa: 'as.numeric (str_replace (x, "NULL", "NA")) ' –

+0

Możliwe obejście? 'x <- c (" 0 "," NULL "," 0 "); y <- x; y [y == "NULL"] <- NA; as.numeric (y) ' – bubble

+1

Muszę czegoś brakować, drugi przykład działa dla mnie' as.numeric (str_replace (x, "NULL", NA)) [1] 0 NA 0' –

Odpowiedz

3

Spójrz na kodzie źródłowym 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> 

To prowadzi do znalezienia fix_replacement, który jest w Github, a ja umieścić go poniżej też. Jeśli uruchomisz go w swoim głównym środowisku, dowiesz się, że fix_replacement(NA) zwraca NA. Widać, że jest on oparty na stri_replace_all_regex, który pochodzi z pakietu stringi.

fix_replacement <- function(x) { 
    stri_replace_all_regex(
     stri_replace_all_fixed(x, "$", "\\$"), 
     "(?<!\\\\)\\\\(\\d)", 
     "\\$$1") 
} 

Interesującą rzeczą jest to, że stri_replace_first_fixed i stri_replace_first_regex zarówno powrócić c(NA,NA,NA) gdy uruchamiane ze swoimi parametrami (twój string, pattern i replacement). Problem polega na tym, że stri_replace_first_fixed i stri_replace_first_regex są kodami C++, więc jest trudniej zorientować się, co się dzieje.

stri_replace_first_fixed można znaleźć here.

stri_replace_first_regex można znaleźć here.

O ile mogę stwierdzić z ograniczonym czasem i moją stosunkowo zardzewiałą znajomością C++, funkcja stri__replace_allfirstlast_fixed sprawdza argument replacement używając stri_prepare_arg_string. Według tego, documentation, spowoduje błąd, jeśli napotka NA. Nie mam czasu, aby w pełni wyśledzić to poza tym, ale podejrzewam, że ten błąd może powodować nieprzewidziany powrót wszystkich NA.

3

To był błąd w pakiecie stringi ale teraz jest fixed (Przypomnijmy, że stringr opiera się na stringi - dawna ma wpływu zbyt).

Dzięki najnowszej wersji rozwojowej otrzymujemy:

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

Nadal dostaję problem używając stringr 1_2_0, który dzwoni stringi_1 .1.5? Chociaż zobacz problem został zamknięty na Github, https://github.com/tidyverse/stringr/issues/110 Każdy pomysł, co się dzieje? Dzięki! – Matifou

Powiązane problemy