2012-08-24 12 views
5

Ho diverse centinaia di vettori di caratteri importati in R da un database, ognuno dei quali ha una lunghezza di 6-7 milioni. Sono dati numerici o fattoriali che hanno carattere (lettere) per le etichette - con i livelli da impostare, tutti i fattori, tutti hanno alcune NA. Ad esempioUso efficiente di as.numeric() e factor()

vecA <- c("1",NA, "2",....,NA, "100") 
vecB <- c("smith", NA, NA, ... , "jones") 

Esiste un modo efficace per forzare vecA in numerico e vecB in fattore. Il problema è che non so dove siano i vettori numerici e fattoriali nei dati ed è noioso esaminarli uno per uno.

+0

questi vettori sono tutti nello stesso oggetto o sono singoli oggetti? Hanno nomi regolari, come nel tuo esempio? –

+0

Chiamerò ogni vettore, uno alla volta da un database, in una funzione. Quella funzione potrebbe essere parallelizzata. Ci saranno caratteri speciali in alcune stringhe - ma solo per i dati del tipo di fattore. – Yoda

risposta

7

probabilmente sarei uso tryCatch(), tentare prima di convertire ogni vettore in classe "numeric". Se as.numeric() genera un messaggio di avviso (come quando il vettore di input contiene caratteri non numerici), prenderei l'avviso e convertirò il vettore in classe "factor".

vecA <- c("1",NA, "2",NA, "100") 
vecB <- c("smith", NA, NA, "jones") 

myConverter <- function(X) tryCatch(as.numeric(X), 
            warning = function(w) as.factor(X)) 

myConverter(vecA) 
# [1] 1 NA 2 NA 100 
myConverter(vecB) 
# [1] smith <NA> <NA> jones 
# Levels: jones smith 
+0

Genius! Grazie mille. – Yoda

1

Forse un'espressione regolare? Per ogni vettore, abbina le cose che assomigliano ai numeri.

convert.numeric <- function(vec) { 
    if(grepl("^[0-9]*(\\.[0-9]+)?$",vec)) == !is.na(vec))) { 
    vec <- as.numeric(vec) 
    } else { vec <- as.factor(vec) } 
    return(vec) 
} 

Poi avvolgere i vettori in un elenco e utilizzare lapply:

new.vectors <- lapply(old.vectors,convert.numeric) 
+1

Potrebbe essere più efficiente testare solo i primi 500 elementi. –

Problemi correlati