пропустить некоторые строки в read.csv в R

У меня есть файл csv, который я читаю, используя следующую функцию:

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

Он читает все строки из этого файла. Но я хочу пропустить некоторые строки из чтения. Строка не должна считываться, если значение столбца ticker равно: ABT или ADCT. Является ли это возможным?

образец моего CSV-файла выглядит следующим образом:

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 

person Dinoop Nair    schedule 12.04.2013    source источник
comment
Используйте readLines и используйте регулярные выражения для фильтрации нежелательных строк.   -  person Roman Luštrik    schedule 12.04.2013
comment
Почему бы не прочитать весь файл и подмножество позже?   -  person A5C1D2H2I1M1N2O1R2T1    schedule 12.04.2013
comment
на самом деле файл имеет размер 200 МБ+, и большинство данных содержат эти значения.   -  person Dinoop Nair    schedule 12.04.2013
comment
Затем вы также можете предварительно обработать файл с помощью sed или csvkit или чего-то подобного и создать меньший файл csv для чтения. Или, как было предложено, изучить пакет sqldf.   -  person A5C1D2H2I1M1N2O1R2T1    schedule 12.04.2013
comment
перед использованием R run: sed '/(,ADCT,|,ABT,)/d' > newfile   -  person topchef    schedule 12.04.2013


Ответы (3)


Это возможно с помощью пакета sqldf, используя read.csv.sql

Допустим, содержимое sample.csv выглядит так:

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

Теперь, чтобы читать только строки, где возраст = 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

Можно выбрать необходимые столбцы:

df <- read.csv.sql("sample.csv", "select id, name from file where age=23")
df
  id name
1  1  "a"
2  3  "c"
person Nishanth    schedule 12.04.2013
comment
Можете уточнить ответ? Тогда это с большей вероятностью поможет вашему ответу привлечь внимание. - person CHP; 12.04.2013
comment
Я обновил свой ответ простым автономным примером. - person Nishanth; 12.04.2013

Лучше прочитать все и подмножество позже, как это предлагается в комментарии:

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

ИЗМЕНИТЬ

Вы можете использовать fread из пакета data.table для более эффективного чтения вашего файла.

library(read.table)
fread(file="pf.csv")
person agstudy    schedule 12.04.2013
comment
Предполагая, что файл слишком велик для чтения в память, какой выбор будет у OP? - person Roman Luštrik; 12.04.2013
comment
на самом деле файл имеет размер 200 МБ+, и большинство данных содержат эти значения. Поэтому я думаю, что это неэффективно. - person Dinoop Nair; 12.04.2013

На первый взгляд пакет sqldf read.csv.sql выглядел великолепно. Но когда я попытался его использовать, он не смог справиться со строками «NULL». (Другие тоже это обнаружили.) К сожалению, он не поддерживает все функции read.csv. Поэтому мне пришлось написать свой собственный. Я удивлен, что для этого нет хорошего пакета.

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: аргумент "объект" должен разобрать строка из одного символа

person Chris    schedule 06.04.2016
comment
read.csv.sql основан на средствах SQLite, а не на read.table, поэтому нельзя ожидать, что он будет работать точно так же; однако аргументы filter= и sql= read.csv.sql могут использоваться для произвольной предварительной обработки, поэтому в зависимости от того, как выглядят ваши данные, обычно можно обрабатывать ситуации с произвольным отсутствующим значением. Например, filter = "sed -e s/NULL//g" удалит все вхождения строки NULL. (В Windows будет предполагаться, что у вас установлен Rtools, и вы получите sed оттуда.) - person G. Grothendieck; 06.04.2016
comment
Я попытался поменять местами NULL с пустыми строками, но это не было интерпретировано как NA. Ваш трюк AFAIK не заставил бы его рассматривать значения как NA. - person Chris; 08.04.2016
comment
Скажем, если это числовое поле, то они будут рассматриваться как 0, и вы можете заменить их на конце R. Или замените NULL на -99, скажем, и замените их на конце R. - person G. Grothendieck; 08.04.2016
comment
Так что немного взлома. Мне пришлось бы выбрать волшебное число и надеяться, что его не существует. 0, -1 и -99 слишком распространены. Моя функция работает быстро, особенно с большими значениями n - person Chris; 08.04.2016