2015-12-17 17 views
9

Sto provando a convertire una stringa di caratteri in numerico e ho riscontrato un comportamento imprevisto con str_replace. Ecco un esempio di lavoro minima:Comportamento imprevisto con 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)) 

A mio avviso, il secondo esempio dovrebbe funzionare come dovrebbe sostituire solo la seconda voce nel vettore con NA (che è un valore valido in un vettore di carattere). Ma non è così: l'interno str_replace converte tutte e tre le voci in NA.

Cosa sta succedendo qui? Ho dato un'occhiata alla documentazione di str_replace e stri_replace_all ma non vedo una spiegazione ovvia.

EDIT: Per chiarire, questo è con stringr_1.0.0 e stringi_1.0-1 su R 3.1.3, Windows 7.

+1

Certamente un comportamento imprevisto nel codice sorgente che ha bisogno di correzione, è necessario fornire NA una stringa per renderlo lavorare: 'as.numeric (str_replace (x, "NULL", "NA")) ' –

+0

Soluzione possibile? 'x <- c (" 0 "," NULL "," 0 "); y <- x; y [y == "NULL"] <- NA; as.numeric (y) ' – bubble

+1

Mi manca qualcosa, il secondo esempio funziona per me' as.numeric (str_replace (x, "NULL", NA)) [1] 0 NA 0' –

risposta

3

guardare il codice sorgente del 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> 

questo porta a trovare fix_replacement, che è al Github, e l'ho messo sotto troppo. Se lo esegui nel tuo ambiente principale, scopri che fix_replacement(NA) restituisce NA. Si può vedere che si basa su stri_replace_all_regex, che è dal pacchetto stringi.

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

La cosa interessante è che stri_replace_first_fixed e stri_replace_first_regex entrambi restituiscono c(NA,NA,NA) quando eseguito con i parametri (il vostro string, pattern, e replacement). Il problema è che stri_replace_first_fixed e stri_replace_first_regex sono codice C++, quindi diventa un po 'più complicato capire cosa sta succedendo.

stri_replace_first_fixed può essere trovato here.

stri_replace_first_regex può essere trovato here.

Per quanto posso discernere con il tempo limitato e la mia conoscenza C++ relativamente arrugginita, la funzione stri__replace_allfirstlast_fixed controlla l'argomento replacement utilizzando stri_prepare_arg_string. Secondo lo documentation per quello, genererà un errore se incontra un NA. Non ho il tempo di rintracciarlo completamente al di là di questo, ma sospetterei che questo errore potrebbe causare lo strano rendimento di tutte le NA.

3

Questo è stato un errore nel pacchetto stringi ma ora è fixed (ricordiamo che stringr si basa sulla stringi - l'ex pregiudica troppo).

Con la più recente versione di sviluppo otteniamo:

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

Ho ancora il problema utilizzando stringr 1_2_0 che chiama stringi_1 .1.5? Sebbene si veda il problema è stato chiuso però su github, https://github.com/tidyverse/stringr/issues/110 Qualche idea di cosa sta accadendo? Grazie! – Matifou