2012-08-24 26 views
5

Tengo varios cientos de vectores de caracteres importados en R desde una base de datos, cada uno tiene una longitud de 6-7 millones. Son datos numéricos o de factores que tienen caracteres (letras) para las etiquetas, con niveles que establecer, todos los factores, todos tienen algunas NA. Como un ejemploUso eficiente de as.numeric() y factor()

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

Hay una manera eficiente de forzar vecA a numeric y vecB a factorizar. El problema es que no sé dónde están los vectores numéricos y de factores en los datos y es tedioso recorrerlos uno por uno.

+0

son estos vectores todos en el mismo objeto, o son objetos individuales? ¿Tienen nombres regulares, como en tu ejemplo? –

+0

Voy a llamar a cada vector, uno a la vez desde una base de datos, en una función. Esa función podría estar paralelizada. Habrá caracteres especiales en algunas de las cadenas, pero solo para los datos del tipo de factor. – Yoda

Respuesta

7

lo que probablemente utilice tryCatch(), tratando primero en convertir cada vector a clase "numeric". Si as.numeric() arroja un mensaje de advertencia (como lo hará cuando el vector de entrada contiene caracteres no numéricos), captaría la advertencia y en su lugar convierta el vector a la clase "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! Muchas gracias. – Yoda

1

¿Quizás una expresión regular? Para cada vector, haga coincidir las cosas que parecen números.

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

Luego envuelva sus vectores en una lista y utilizar lapply:

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

Puede ser más eficiente para probar solo los primeros 500 elementos. –