2012-02-01 19 views
5

Ho un dataframe in R che ho caricato da un file CSV. Una delle variabili è chiamata "Quantità" e intende contenere numeri positivi e negativi.R - Da errore fattoriale a numerico o intero

Quando ho guardato il dataframe, il tipo di dati di questa variabile è elencato come un fattore, e ne ho bisogno in un formato numerico (Non sono sicuro quale tipo se - intero - numerico, umm ...?). Così, ho provato a convertirlo in uno di questi due formati, ma ho visto alcuni comportamenti interessanti.

dataframe iniziale:

str(df) 

Amount  : Factor w/ 11837 levels "","-1","-10",..: 2 2 1664 4 6290 6290 6290 6290 6290 6290 ... 

Come ho già detto, ho visto qualcosa di strano quando ho cercato di convertirlo in uno numerico o intero. Per mostrare questo, ho messo insieme questo confronto:

df2 <- data.frame(df$Amount, as.numeric(df$Amount), as.integer(df$Amount)) 

str(df2) 
'data.frame': 2620276 obs. of 3 variables: 
$ df.Amount   : Factor w/ 11837 levels "","-1","-10",..: 2 2 1664 4 6290 6290 6290 6290 6290 6290 ... 
$ as.numeric.df.Amount.: num 2 2 1664 4 6290 ... 
$ as.integer.df.Amount.: int 2 2 1664 4 6290 6290 6290 6290 6290 6290 ... 

> head(df2, 20) 
     df.Amount  as.numeric.df.Amount.  as.integer.df.Amount. 
1    -1       2       2 
2    -1       2       2 
3    -201      1664      1664 
4    -100       4       4 
5    1      6290      6290 
6    1      6290      6290 
7    1      6290      6290 
8    1      6290      6290 
9    1      6290      6290 
10    1      6290      6290 
11    1      6290      6290 
12    1      6290      6290 
13    1      6290      6290 
14    1      6290      6290 
15    1      6290      6290 
16    1      6290      6290 
17    1      6290      6290 
18    2      7520      7520 
19    2      7520      7520 
20    2      7520      7520 

I as.numeric e as.integer funzioni stanno prendendo la variabile Importo e fare qualcosa per essa, ma non sanno che questo è. Il mio obiettivo è di ottenere la variabile Amount in una sorta di tipo di dati numerico in modo da poter eseguire sum/mean/etc su di esso.

Che cosa sto facendo in modo errato che causa i numeri strani e cosa posso fare per risolverlo?

risposta

10

La radice del problema è probabilmente un valore funky nel tuo csv importato. Se proviene da Excel, questo non è raro. Può essere un simbolo di percentuale, un carattere di "commento" da excel o da una lunga lista di cose. Guarderei il CSV nel tuo editor di scelta e vedere cosa puoi vedere.

A parte questo, hai alcune opzioni.

read.csv prende un argomento opzionale stringsAsFactors che è possibile impostare per FALSE

Un fattore viene memorizzato come i livelli di interi che mappano ai valori. Quando si converte direttamente con as.numeric si finisce con quei livelli interi piuttosto che i valori iniziali:

> x<-10:20 
> as.numeric(factor(x)) 
[1] 1 2 3 4 5 6 7 8 9 10 11 
> 

altrimenti un'occhiata a ?factor:

In particolare, as.numeric applicata ad un fattore non ha senso, e può accadere con una coercizione implicita. Per trasformare un fattore f in circa i suoi valori numerici originali , è consigliabile as.numeric(levels(f))[f] e leggermente più efficiente di as.numeric(as.character(f)).

Tuttavia, ho il sospetto che questo errore si verificherà perché l'input contiene qualcosa oltre a un numero.

+0

volta la colonna in questione è un personaggio, piuttosto che fattore, sono stato in grado di trovare la fonte di questo tipo di problema abbastanza rapidamente utilizzando 'grep' o' grepl' a controlla alcuni probabili sospetti. – joran

+0

+1 buona risposta. Ho ampliato un po 'la mia risposta su come trovare i valori offendenti ... – Tommy

+0

Spazzatura in .... Alcune virgole hanno causato il problema. Grazie per l'assistenza. – mikebmassey

10

@Justin è corretto. Ecco un walk-through su come trovare i valori di offendere:

# A sample data set with a weird value ("4%") in it 
d <- read.table(text="A B\n1 2\n3 4%\n", header=TRUE) 
str(d) 
#'data.frame': 2 obs. of 2 variables: 
# $ A: int 1 3 
# $ B: Factor w/ 2 levels "2","4%": 1 2 

as.numeric(d$B) # WRONG, returns 1 2 (the internal factor codes) 

# This correctly converts to numeric 
x <- as.numeric(levels(d$B))[d$B] # 2 NA 

# ...and this finds the offending value(s): 
d$B[is.na(x)] # 4% 

# and this finds the offending row numbers: 
which(is.na(x)) # row 2 

Nota che se il set di dati sono i valori mancanti codificato come qualcosa di diverso da una cella vuota o la stringa "NA", è necessario specificare che, per read.table:

# Here "N/A" is used instead of "NA"... 
read.table(text="A B\n1 2\n3 N/A\n", header=TRUE, na.strings="N/A") 
1

Sono nuovo qui ma ho utilizzato questo forum per le mie domande.Stavo avendo problemi simili ma il sotto funzionava per me. Sono porting dati da file txt al frame di dati

data <- read.delim(paste(folderpath,"data.txt",sep=""),header=TRUE,sep="\\",as.is=6) 

noti che ho usato as.is colonna 6 che aveva dati numerici e anche alcuni caratteri garbage in alcune righe. Usando as.is porta i dati come caratteri nella colonna 6. quindi i seguenti hanno cambiato i caratteri nella colonna 6 in valori numerici. tutti i valori di garbage sono stati convertiti in NA che potrebbe essere rimosso in seguito.

data[,6] <- as.numeric(data[,6]) 

Spero che questo aiuti

Problemi correlati