2012-05-04 7 views
6

tengo un archivo que he leído en en R y se traduce a una trama de datos (llamada CA1) para tener la estructura como sigue:la conversión de un personaje en un valor numérico en I

Station_ID Guage_Type Lat Long  Date Time_Zone Time_Frame H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 H11 H12 H13 H14 H15 H16 H17 H18 H19 H20 H21 H22 H23 
1 4457700   HI 41.52 124.03 19480701   8  LST 0 0 0 0 0 0 0 0 0 0 0 0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS 
2 4457700   HI 41.52 124.03 19480705   8  LST 0 1 1 1 1 1 2 2 2 4 5 5 4 7 1 1 0 0 10 13 5 1 1 3 
3 4457700   HI 41.52 124.03 19480706   8  LST 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
4 4457700   HI 41.52 124.03 19480727   8  LST 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
5 4457700   HI 41.52 124.03 19480801   8  LST 0 0 0 0 0 0 0 0 0 0 0 0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS 
6 4457700   HI 41.52 124.03 19480817   8  LST 0 0 0 0 0 0 ACC ACC ACC ACC ACC ACC 6 1 0 0 0 0 0 0 0 0 0 0 

H0 través de H23 son leer como carácter() ya que habrá casos en que el valor no será numérico y tendrá valores como MIS, ACC o DEL.

Mi pregunta: hay una manera de encasillar los valores para cada columna H0 a H23 para que sean numéricos y tengan los valores de caracteres (MIS, ACC, DEL) como NA o NAN que puedo probar si son (is.nan o is.na) para que pueda ejecutar algunos modelos numéricos en él. ¿O sería mejor cambiar los valores de los caracteres a un identificador, como -9999?

Lo he intentado de muchas maneras. He encontrado algunos en este sitio, pero nada de trabajo. Tales como:

for (i in 8:31) 
{ 
    CA1[6,i] <- as.numeric(as.character(CA1[6,i])) 
} 

que por supuesto da advertencias pero como prueba si dos valores específicos is_numeric() (CA1 [6,8] y CA1 [6,19]) que reciben una declaración falsa para ambos. El primero no entiendo por qué, pero el segundo lo hago ya que es un "". Sin embargo, puedo probar eso con is.na (CA1 [6,19]) y devuelve verdadero, lo cual está bien para mí saber que no es numérico.

Una segunda manera he intentado es:

for (i in 8:31) 
{ 
    CA1[6,i] <- as.numeric(levels(CA1[6,i]))[CA1[6,i]] 
} 

la que consigo los mismos resultados que antes.

¿Hay alguna manera de hacer lo que estoy tratando de hacer de manera eficiente? Tu ayuda es muy apreciada. Gracias

Respuesta

6

El problema inmediato es que cada columna de un marco de datos solo puede contener valores de un tipo. El 6 en CA1[6,i] en su código significa que solo se está convirtiendo un único valor en cada columna, por lo que, cuando se inserta después de la conversión, se lo coacciona de nuevo a una cadena para que coincida con el resto de la columna.

Puede resolver esto convirtiendo la columna completa de una sola vez, de modo que la columna se sustituya por completo. es decir, quitar el 6:

for (i in 8:31) 
{ 
    CA1[,i] <- as.numeric(as.character(CA1[,i])) 
} 
+0

gracias por su ayuda, tiene razón acerca de la conversión a una cadena para que coincida con la columna. La razón por la que puse el 6 fue solo para probarlo en una fila para ver si funcionaba, pero desafortunadamente la pequeña prueba era la raíz de mi problema. Sin embargo, gracias por tu ayuda. –

6

Cuando lee los datos, normalmente puede especificar cuáles son los tipos de columna. Por ejemplo, read.table/read.csv tienen un argumento colClasses.

# Something like this 
read.table('foo.txt', header=TRUE, colClasses=c('integer', 'factor', 'numeric', numeric', 'Date')) 

Consulte ?read.table para obtener más información.

2

Tras la respuesta de Tommy, que potencialmente podría hacer frente a este problema en la lectura de los datos. Si "MIS", "ACC" y "DEL" siempre denotan valores faltantes, puede usar el argumento na.strings en read.table.

read.table('foo.txt', header=TRUE, na.strings = c("MIS", "ACC", "DEL")) 

Si hay otras cadenas de caracteres que siempre denotan los valores que faltan, entonces se podría añadirlos al vector anterior.

Sin embargo, si, por ejemplo, "MIS" aparece en la columna Time_Frame y tiene un significado que no sea para indicar un valor faltante, entonces NO TOME ESTE ENFOQUE !!

+0

Gracias por su ayuda, sin embargo, estoy leyendo los datos como un marco de datos en tres líneas, ya que no está organizado. El fragmento de código que vio en mi publicación es la forma en que lo limpié. Sin embargo, lo intenté usando na.strings = c ("MIS", "ACC", "DEL") como lo mencionaste, aunque tengo el mismo problema cuando se escribe en los datos ya que la mayoría de los datos en la columna es tipo de carácter (como se explica por dpaupp). Pero su método es excelente y definitivamente lo tendré en cuenta para usarlo en el futuro. Gracias por tu ayuda –

Cuestiones relacionadas