使用R在文本字段中读取包含未加引号的换行符的文件

时间:2014-01-07 00:53:20

标签: regex r newline read.table

我正在尝试将一个大表读入R中,但其中一个文本字段偶尔会包含一个或多个未加引号,未转义的换行符(\n),因此read.table()函数无法使用轻松导入此文件。该文件以管道分隔,并且未引用文本字段。

如果我将参数fill=Tread.table()一起传递,我可以阅读它,但是,当然,文本字段中带有换行符的行会被此损坏。

我已成功使用f <- readChar(fname, nchars=file.info(fname)["size"], TRUE)来读取文件的子段,然后使用gsub()搜索并销毁有问题的换行符。 (参见下面的代码)但是,完整的文件是&gt; 100mb,所以gsub()只会把我的笔记本电脑变成一个暖手器(它仍然试图在写这篇文章的时候gsub所有换行符)。

有人对如何有效地读取这样的文件有任何建议吗?

似乎应该有一些方法告诉R在期望换行之前期望一定数量的分隔符,但我在文档中找不到任何方法来执行此操作。

对不起,这看起来应该很容易,但它真的让我很难过,而且我无法在stackoverflow或谷歌提供解决方案中找到任何东西。

这是我到目前为止尝试过的代码:

尝试1:

fdat = read.table(file=fname, 
            allowEscapes=F,
            stringsAsFactors=F,
            quote="", 
            fill=T,
            strip.white=T,
            comment.char="",
            header=T, 
            sep="|")

尝试2:

f <- readChar(fname, nchars=file.info(fname)["size"], TRUE)
f2 = gsub(pattern="\n(?!NCT)",replacement=" ",x=f, perl=T)
fdat = read.table(text=f2,
            allowEscapes=F,
            stringsAsFactors=F,
            quote="", 
            fill=F,
            strip.white=T,
            comment.char="",
            header=T, 
            sep="|")

以下是文件中的几行:

NCT_ID|DOWNLOAD_DATE|DOWNLOAD_DATE_DT|ORG_STUDY_ID|BRIEF_TITLE|OFFICIAL_TITLE|ACRONYM|SOURCE|HAS_DMC|OVERALL_STATUS|START_DATE|COMPLETION_DATE|COMPLETION_DATE_TYPE|PRIMARY_COMPLETION_DATE|PRIMARY_COMPLETION_DATE_TYPE|PHASE|STUDY_TYPE|STUDY_DESIGN|NUMBER_OF_ARMS|NUMBER_OF_GROUPS|ENROLLMENT_TYPE|ENROLLMENT|BIOSPEC_RETENTION|BIOSPEC_DESCR|GENDER|MINIMUM_AGE|MAXIMUM_AGE|HEALTHY_VOLUNTEERS|SAMPLING_METHOD|STUDY_POP|VERIFICATION_DATE|LASTCHANGED_DATE|FIRSTRECEIVED_DATE|IS_SECTION_801|IS_FDA_REGULATED|WHY_STOPPED|HAS_EXPANDED_ACCESS|FIRSTRECEIVED_RESULTS_DATE|URL|TARGET_DURATION|STUDY_RANK
NCT00000105|Information obtained from ClinicalTrials.gov on September 25, 2012|9/25/2012|2002LS032|Vaccination With Tetanus and KLH to Assess Immune Responses.|Vaccination With Tetanus Toxoid and Keyhole Limpet Hemocyanin (KLH) to Assess Antigen-Specific Immune Responses||Masonic Cancer Center, University of Minnesota|Yes|Terminated|July 2002|March 2012|Actual|March 2012|Actual|N/A|Observational|Observational Model:  Case Control, Time Perspective:  Prospective||3|Actual|112|Samples With DNA|analysis of blood samples before and 4 weeks postvaccination|Both|18 Years|N/A|Accepts Healthy Volunteers|Probability Sample|-  Normal volunteers

          -  Patients with Cancer (breast, melanoma, hematologic)

          -  Transplant patients (umbilical cord blood transplant, autologous transplant)

          -  Patients receiving other cancer vaccines|March 2012|March 26, 2012|November 3, 1999|Yes|Yes|Replaced by another study.|No||http://clinicaltrials.gov/show/NCT00000105||6670
NCT00000106|Information obtained from ClinicalTrials.gov on September 25, 2012|9/25/2012|NCRR-M01RR03186-9943|41.8 Degree Centigrade Whole Body Hyperthermia for the Treatment of Rheumatoid Diseases|||National Center for Research Resources (NCRR)||Active, not recruiting||||||N/A|Interventional|Allocation:  Randomized, Intervention Model:  Parallel Assignment, Primary Purpose:  Treatment|||||||Both|18 Years|65 Years|No|||November 2000|June 23, 2005|January 18, 2000||||No||http://clinicaltrials.gov/show/NCT00000106||7998

可以看出,我的问题文件中的这些样本行包括标题(第1行),有问题的行(第2行)和无问题的行(第3行)。每个非标题行以NCT开头,以\ n结尾(这是在gsub的正则表达式中使用的)。

非常感谢任何建议。

1 个答案:

答案 0 :(得分:2)

似乎没有办法使用read.table来解决它。可悲的是,它不允许像awk那样改变“记录分隔符”,例如。

您的尝试2失败,因为DOS格式换行符是\ r \ n(0x0d 0x0a)且只有\ n由gsub匹配。假设您有以下文件:

NCTa|b|c
NCT1|how
are
you?|well
NCT2|are
you
sure?|yes

然后查看第二个命令的输出:

f2 <- gsub(pattern="\n(?!NCT)",replacement=" ",x=f, perl=TRUE)
f2
# [1] "NCTa|b|c\r\nNCT1|how\r are\r you?|well\r\nNCT2|are\r you\r sure?|yes\r "

所以你必须删除\r。只需将其修复为:

f2 <- gsub(pattern="\r?\n(?!NCT)",replacement=" ",x=f, perl=TRUE)

它会起作用。

关于性能,您可以尝试readChar循环中的较小块,gsub并将它们写回文件,然后read.table。只是一个想法。