2013-04-12 16 views
10

Mam pliku csv które odczytać za pomocą następujących funkcji:pominąć niektóre wiersze w read.csv w 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") 

odczytuje wszystkie linie z tego pliku. Ale chcę pominąć niektóre wiersze od czytania. Wiersz nie powinien odczytywać, jeśli wartość kolumny wynosi: ABT lub . Czy to możliwe?

próbka mojego pliku csv jest następujący:

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

Wykorzystanie 'readLines' i używać wyrażeń regularnych odfiltrowanie niepożądanych wierszy. –

+1

Dlaczego nie przeczytać w całości pliku i podzestawu później? – A5C1D2H2I1M1N2O1R2T1

+0

faktycznie plik zawierający 200 MB + i większość danych zawiera te wartości. –

Odpowiedz

18

Jest to możliwe przy użyciu sqldf package, używając read.csv.sql

Powiedzmy zawartość sample.csv wygląda następująco:

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

teraz czytać tylko wiersze, gdzie wiek = 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 

Możliwe jest wybranie niezbędnych kolumn:

df <- read.csv.sql("sample.csv", "select id, name from file where age=23") 
df 
    id name 
1 1 "a" 
2 3 "c" 
+1

Czy możesz rozwinąć odpowiedź? Wtedy bardziej prawdopodobne będzie, że Twoja odpowiedź zwróci na siebie uwagę. –

+0

Zaktualizowałem swoją odpowiedź za pomocą prostego, samodzielnego przykładu. – Nishanth

+2

+1 dla szczegółowej odpowiedzi;) –

1

Lepiej przeczytać i podzbiór później jak sugeruje w komentarzu:

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

EDIT

Ty można użyć pakietu fread z data.table dla bardziej wydajnej metody odczytu pliku.

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

Zakładając, że plik był zbyt duży, aby go wczytać do pamięci, jakie byłyby wówczas wybory OP? –

+2

faktycznie plik mający 200 MB + i większość danych zawiera te wartości. Więc myślę, że to nie jest wydajne. –

0

Dla mnie read.csv.sql pakietu sqldf wyglądała świetnie na pierwszy rzut oka. Ale kiedy próbowałem go użyć, nie radził sobie z ciągami "NULL". (Inni też to odkryli). Niestety, nie obsługuje wszystkich funkcji read.csv. Więc musiałem napisać własne. Jestem zaskoczony, że nie ma dobrego pakietu.

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' bazuje na SQLite, nie na" read.table ", więc nie można się spodziewać, że działa dokładnie tak samo; jednakże argumenty 'filter =' i 'sql =' z 'read.csv.sql' mogą być użyte do dowolnego przetwarzania, więc w zależności od tego, jak twoje dane wyglądają jak arbitralne sytuacje z brakującymi wartościami, zazwyczaj można sobie z nimi poradzić.Na przykład 'filter =" sed -e s/NULL // g "' usunie wszystkie wystąpienia ciągu NULL. (W Windowsie zakłada się, że masz zainstalowane Rtools i otrzymujesz sed od tego miejsca.) –

+0

Próbowałem zamieniać NULL na puste ciągi, ale nie było to interpretowane jako NA. Twoja sztuczka AFAIK nie sprawi, że potraktuje wartości jako NA. – Chris

+0

Jeśli jest to pole numeryczne, powiedzmy, że będą one traktowane jako 0 i można je zastąpić na końcu R. Lub zamień NULL na -99, powiedzmy, i zamień je na koniec R. –

Powiązane problemy