读取带隐藏或不可见字符的csv文件^ M.

时间:2014-01-23 23:04:07

标签: r csv

我尝试读取包含隐藏或不可见字符的* .csv文件失败。文件内容如下所示:

my.data2 <- read.table(text = '
Common.name, Scientific.name, Stuff1, Stuff2
Greylag.Goose, Anser.anser, AAC, rr
Snow.Goose, Anser.caerulescens, AAC, rr
Greater.Canada.Goose, Branta.canadensis, AAC, rr
Barnacle.Goose, Branta.leucopsis, AAC, rr
Brent.Goose, Branta.bernicla, AAC, rr
', header = TRUE, sep=',', stringsAsFactors = FALSE)

请注意,上面的read.table命令可以正确读取数据。但是,read.csv无法正确读取文件,因为在许多行中,第二个空格后面有一个隐藏字符。在某些行中,第一个空格后面还有一个隐藏字符。在某些行中没有隐藏的字符。例如:

setwd('c:/users/mmiller21/simple R programs')

my.data <- read.csv('invisible.delimiter2.csv', header = TRUE)
my.data

返回:

            Common.name    Scientific.name Stuff1 Stuff2
1         Greylag.Goose        Anser.anser              
2                   AAC                 rr              
3            Snow.Goose                                 
4    Anser.caerulescens                                 
5                   AAC                 rr              
6  Greater.Canada.Goose  Branta.canadensis    AAC     rr
7        Barnacle.Goose   Branta.leucopsis              
8                   AAC                 rr              
9           Brent.Goose    Branta.bernicla              
10                  AAC                 rr              

更具体地说,如果我在记事本中打开* .csv文件并使用右箭头键沿第一行数据移动光标,我必须按两次右箭头键移动到第一行{{ 1}} A

以下行无法解决问题:

AAC

根据我的经验,标签是一个相当常见的隐藏字符或分隔符。但是,我尝试过搜索和替换标签,但这没有用。

我也尝试将* .csv文件转换为* .txt文件,但会返回以下内容:

my.data <- read.csv('invisible.delimiter2.csv', sep=',', header = TRUE)

我不熟悉其他可能的解决方案。该文件太大,无法手动搜索每个空格中的隐藏字符并将其删除。

感谢您提供有关如何阅读此类文件或如何在将文件读入R之前查找和删除隐藏字符的任何建议。

如果有帮助,我最初是通过复制维基百科中的表来获取数据的。也许这可能有助于识别隐藏的角色。

修改

感谢下面的评论,我使用gVim 7.3打开了示例数据文件。该软件显示隐藏的字符并将其显示为> my.data3 <- read.table('invisible.delimiter2.txt', sep=',', header = TRUE) Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings, : line 1 did not have 4 elements > my.data3 Error: object 'my.data3' not found 。不幸的是,我无法通过gVim 7.3中的简单查找和替换从数据文件中删除该字符。如果我想出如何删除^M,我会在这里发布方法。

以下是有关如何使用Perl删除^M的帖子。

In Perl, how to remove ^M from a file?

希望我能弄明白如何用R或文本编辑器删除它

以下是存储示例* .csv文件的链接。

https://github.com/markwmiller/Rcode/blob/93d07bd2e389e516b6da92017e025a1e97173db0/invisible.delimiter2.csv

和同一网站上同一文件的替代链接:

https://github.com/markwmiller/Rcode

3 个答案:

答案 0 :(得分:3)

在gVim中,您应该可以通过键入以下内容来删除^ M字符:

:%s/<ctrl>V<ctrl>M//g<return>

如果您输入的内容正确,则会显示为&#39;:%s / ^ M // g&#39;在gVim。按返回时,gVim会搜索(&#39; s&#39;)第一个和第二个斜杠之间的内容,并将其替换为全局第二个和第三个斜杠之间的内容(& #39;克&#39;。)

注意:如果您在Windows框中并且&lt; ctrl&gt; V似乎粘贴文本,那么gVim可能配置了&#39; windows行为&#39;。在这种情况下,使用&lt; ctrl&gt; Q&lt; ctrl&gt; M而不是&lt; ctrl&gt; V&lt; ctrl&gt; M。

当我将样本文件加载到gVim 7.3中时,它看起来像这样:

enter image description here

输入字符后

:%s/<ctrl>V<ctrl>M//g

但是在回来之前我看到了:

enter image description here

点击返回后我看到了:

enter image description here

然后,您可以执行文件 - &gt;保存或文件 - &gt;另存为,这会做您期望的事情。

答案 1 :(得分:1)

以下是使用scan来读取数据的解决方案,matrix来构建数据,data.frame使其成为数据框:

readF <- function(path, nfields=4){    
    m = matrix(
          gsub(",","",scan(path,what=rep("",nfields))),
              ncol=nfields,byrow=TRUE)
    d = data.frame(m[-1,])
    names(d)=m[1,]
    d
}

首先检查文件是否重复了您的问题:

> read.csv("./invisible.delimiter2.csv")
            Common.name    Scientific.name Stuff1 Stuff2
1         Greylag.Goose        Anser.anser              
2                   AAC                 rr              
3            Snow.Goose                                 
4    Anser.caerulescens                                 
5                   AAC                 rr              
6  Greater.Canada.Goose  Branta.canadensis    AAC     rr
7        Barnacle.Goose   Branta.leucopsis              
8                   AAC                 rr              
9           Brent.Goose    Branta.bernicla              
10                  AAC                 rr        

然后看看我的函数是否解决了它:

> readF("./invisible.delimiter2.csv")
Read 24 items
           Common.name    Scientific.name Stuff1 Stuff2
1        Greylag.Goose        Anser.anser    AAC     rr
2           Snow.Goose Anser.caerulescens    AAC     rr
3 Greater.Canada.Goose  Branta.canadensis    AAC     rr
4       Barnacle.Goose   Branta.leucopsis    AAC     rr
5          Brent.Goose    Branta.bernicla    AAC     rr

随意选择该功能,看看它是如何工作的。

我怀疑问题的根源是^ M在字段数据中,并且因为你没有引用字段,所以R无法判断它是真实的行结尾还是字段中的结果。在read.csv等文档的引用字段中有一些关于嵌入换行符的注释。

答案 2 :(得分:0)

以下是可以处理字段中的空白区域(即多个单词)的代码:

nfields <- 4

bb <- readLines('c:/users/mmiller21/simple R programs/invisible.delimiter4.csv')
bb

pattern <- "(?<=\\,)(?=)"                  # split on commas
cc <- strsplit(bb, pattern, perl=TRUE)
dd <- unlist(cc)
ee <- dd[dd != ' ' & dd != '' & dd != ','] # remove empty elements
ff <- gsub(",", "", ee)                    # remove commas

m = matrix(ff, ncol=nfields, byrow=TRUE)   # store data in matrix

# returns string w/o leading or trailing whitespace
trim <- function (x) gsub("^\\s+|\\s+$", "", x)
nn <- trim(m)
nn

以下是原始数据集的内容:

Common.name, Scientific.name, Stuff1, Stuff2
Greylag Goose, Anser anser, AAC aa, rr bb
Snow Goose, Anser caerulescens, AAC aa aa, rr bb bb
Greater Canada Goose, Branta canadensis, AAC, rr bb
Barnacle Goose, Branta leucopsis, AAC aa, rr
Brent Goose, Branta bernicla, AAC, rr bb bb bb

我简单地删除了常用名和科学名称中的点,并在第三和第四列中添加了额外的文字。

这是输出:

     [,1]                   [,2]                 [,3]        [,4]         
[1,] "Common.name"          "Scientific.name"    "Stuff1"    "Stuff2"     
[2,] "Greylag Goose"        "Anser anser"        "AAC aa"    "rr bb"      
[3,] "Snow Goose"           "Anser caerulescens" "AAC aa aa" "rr bb bb"   
[4,] "Greater Canada Goose" "Branta canadensis"  "AAC"       "rr bb"      
[5,] "Barnacle Goose"       "Branta leucopsis"   "AAC aa"    "rr"         
[6,] "Brent Goose"          "Branta bernicla"    "AAC"       "rr bb bb bb"