2013-04-12 13 views
10

Ho un file csv che ho letto utilizzando la seguente funzione:saltare alcune righe read.csv in R

csvData <- read.csv(file="pf.csv", colClasses=c(NA, NA,"NULL",NA,"NULL",NA,"NULL","NULL","NULL")) 
dimnames(csvData)[[2]]<- c("portfolio", "date", "ticker", "quantity") 

Legge tutte le righe di tale file. Ma voglio saltare alcune righe dalla lettura. La riga non dovrebbe essere letta se il valore della colonna ticker è: ABT o ADCT. È possibile?

campione del mio file CSV è il seguente:

RUS1000,01/29/1999,21st Centy Ins Group,TW.Z,90130N10,72096,1527.534,0.01,21.188 
RUS1000,01/29/1999,3com Corp,COMS,88553510,358764,16861.908,0.16,47.000 
RUS1000,01/29/1999,3m Co,MMM,88579Y10,401346,31154.482,0.29,77.625 
RUS1000,01/29/1999,A D C Telecommunicat,ADCT,00088630,135114,5379.226,0.05,39.813 
RUS1000,01/29/1999,Abbott Labs,ABT,00282410,1517621,70474.523,0.66,46.438 
RUS1000,02/26/1999,21st Centy Ins Group,TW.Z,90130N10,72096,1378.836,0.01,19.125 
RUS1000,02/26/1999,3com Corp,COMS,88553510,358764,11278.644,0.11,31.438 
RUS1000,02/26/1999,3m Co,MMM,88579Y10,402146,29783.938,0.29,74.063 
+3

Usa 'readLines' e utilizzare espressioni regolari per filtrare le righe indesiderate. –

+1

Perché non leggere l'intero file e il sottoinsieme in un secondo momento? – A5C1D2H2I1M1N2O1R2T1

+0

effettivamente il file con 200mb + e la maggior parte dei dati contiene questi valori. –

risposta

18

E 'possibile utilizzare sqldf package, utilizzando read.csv.sql

Diciamo che il contenuto di sample.csv aspetto:

id,name,age 
1,"a",23 
2,"b",24 
3,"c",23 

Ora di leggere solo le righe in cui l'età = 23:

require(sqldf) 

df <- read.csv.sql("sample.csv", "select * from file where age=23") 

df 
    id name age 
1 1 "a" 23 
2 3 "c" 23 

E 'possibile selezionare le colonne necessarie:

+1

Puoi elaborare la risposta? Allora sarà più probabile che la tua risposta attiri attenzione. –

+0

Ho aggiornato la mia risposta con un semplice esempio indipendente. – Nishanth

+2

+1 per la risposta dettagliata;) –

1

E 'meglio leggere tutto e sottoinsieme successivamente come suggerito nel commento:

csvData [!csvData$ticker %in% c('ADCT','ABT'),] 

EDIT

È possibile utilizzare fread dal pacchetto data.table per un metodo più efficiente per leggere il file.

library(read.table) 
fread(file="pf.csv") 
+4

Supponendo che il file fosse troppo grande per essere letto in memoria, quali sarebbero OP le scelte allora? –

+2

effettivamente il file con 200mb + e la maggior parte dei dati contiene questi valori. Quindi penso che non sia efficiente. –

0

Per me il pacchetto sq.csv.sql del file sqldf è sembrato ottimo a prima vista. Ma quando ho provato ad usarlo, non è riuscito a gestire le stringhe "NULL". (Anche altri lo hanno scoperto). Sfortunatamente, non supporta tutte le funzionalità di read.csv. Quindi ho dovuto scrivere il mio. Sono sorpreso che non ci sia un buon pacchetto per questo.

fetchLines=function(inputFile,match,fixed=T,n=100,maxlines=100000){ #inputFile='simple.csv'; match='APPLE'; 
    message('reading:',inputFile) 
    n=min(n,maxlines) 
    con <- base::file(inputFile, open = "r",encoding = "UTF-8-BOM") 
    data=c(readLines(con, n = 1, warn = FALSE)) 
    while (length(oneLine <- readLines(con, n = n, warn = FALSE)) > 0) { 
    grab=grep(match,oneLine,value=T,fixed=fixed) 
    if(length(grab)>0){ 
     data=c(data,grab) 
     if(length(data)>maxlines){ 
     warning("bailing out too many"); 
     return(data); 
     } 
     cat('.') 
    } 
    } 
    close(con) 
    gc() 
    cat("\n") 
    data; 
} 

#To avoid: argument 'object' must deparse to a single character string 
fdata=textConnection(fetchLines("datafile.csv",'\\bP58\\b',fixed=F,maxlines = 100000)) 
df<-read.csv(fdata,header=T,sep=",",na.strings = c('NULL',''),fileEncoding = "UTF-8-BOM",stringsAsFactors = F) 

R textConnection: "argument 'object' must deparse to a single character string"

+0

'read.csv.sql' è basato su servizi SQLite, non su' read.table', quindi non ci si può aspettare che funzioni esattamente allo stesso modo; tuttavia, gli argomenti 'filter =' e 'sql =' di read.csv.sql' possono essere usati per la preprocessazione arbitraria, quindi a seconda di come i dati sembrano situazioni di valore mancanti arbitrarie possono essere normalmente gestite.Ad esempio, 'filter =" sed -e s/NULL // g "' rimuoverà tutte le occorrenze della stringa NULL. (Su Windows si suppone che Rtools sia installato e scaricato da lì.) –

+0

Ho provato a scambiare NULL con stringhe vuote ma non è stato interpretato come NA. Il tuo trucco AFAIK non lo farebbe trattare i valori come NA. – Chris

+0

Se è un campo numerico, ad esempio, verrà considerato come 0 e sarà possibile sostituirli sul lato R. Oppure sostituire NULL con -99, ad esempio, e sostituirli sul lato R. –

Problemi correlati