2013-04-12 75 views
10

我有予读取使用下面的函数csv文件:跳过read.csv某些行中的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") 

它读取从该文件中的所有行。但我想从阅读中跳过一些行。如果ticker列的值为:ABTADCT,则该行不应读取。可能吗?我的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 
+3

使用'readLines'和使用正则表达式过滤掉不良行。 –

+1

为什么不在以后读整个文件和子集? – A5C1D2H2I1M1N2O1R2T1

+0

实际上文件有200mb +,大部分数据都包含这些值。 –

回答

18

有可能使用sqldf package,使用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" 
+1

你能否详细说明答案?那么它将更有可能帮助你的答案获得关注。 –

+0

我已经用一个简单的,自包含的示例更新了我的答案。 – Nishanth

+2

+1以获得详细答案; –

1

这是更好地阅读所有与子集以后类似建议的评论:

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

编辑

你可以使用来自data.table包,以更高效地读取文件。

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

假设文件太大而无法读入内存,那么OP的选择是什么呢? –

+2

实际上有200mb +的文件和大多数数据包含这些值。所以我认为这是不高效的。 –

0

对我来说,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: "argument 'object' must deparse to a single character string"

+0

'read.csv.sql'基于SQLite工具,而不是'read.table',所以人们无法真正期望它的工作原理完全相同;然而,'read.csv.sql'的'filter ='和'sql ='参数可以用于任意的预处理,所以根据你的数据看起来像通常可以处理任意缺失值的情况。例如,'filter =“sed -e s/NULL // g”'将删除所有出现的字符串NULL。 (在Windows上,它会假设你已经安装了Rtools并从那里获得sed。) –

+0

我尝试用空字符串交换NULL,但它不被解释为NA。你的绝招AFAIK不会将它视为NA。 – Chris

+0

如果它是一个数字字段,那么它们将被视为0,并且您可以在R端替换它们。或者用-99替换NULL,比方说,将它们替换为R端。 –