读取toad导出的csv文件后,将奇怪的字符添加到第一列名称

时间:2014-04-09 21:58:06

标签: r csv toad

每当我读取使用toad导出的R(csv)中的read.csv("file_name.csv")文件时,第一列名称前面都会出现以下字符“ï.. ” 。此外,打开excel或notepad ++中的csv文件正确显示(没有前面的字符)。这是一个麻烦,因为我的解决方法是在每次读取后重命名该列。 感谢您解决此问题!

编辑:
通过右键单击查询的结果集并选择“快速导出 - >”,在Toad中创建导出。档案 - > CSV文件'

每条评论的更多细节:
    head(readLines('test_file.csv'),n=3)
    [1] "ID,LOCATION" "12021,1204" "12281,1204"

4 个答案:

答案 0 :(得分:18)

试试这个:

d <- read.csv("test_file.csv", fileEncoding="UTF-8-BOM")

这适用于R 3.0.0+并删除文件中存在的BOM(对于从Microsoft应用程序生成的文件很常见:Excel,SQL server)

答案 1 :(得分:2)

我最近在剪贴板和Microsoft Excel中都遇到了这个问题

随着用于数据科学的多语言内容的不断增长,再也没有一种安全的方法来假定utf-8(在我的情况下,excel假定使用UTF-16,因为我的大多数数据都包括繁体中文(普通话) ?)。

根据Microsoft Docs,Windows中使用了以下BOM:

|----------------------|-------------|-----------------------|
| Encoding             | Bom         | Python encoding kwarg |
|----------------------|-------------|-----------------------|
| UTF-8                | EF BB BF    | 'utf-8'               |
| UTF-16 big-endian    | FE FF       | 'utf-16-be'           |
| UTF-16 little-endian | FF FE       | 'utf-16-le'           |
| UTF-32 big-endian    | 00 00 FE FF | 'utf-32-be'           |
| UTF-32 little-endian | FF FE 00 00 | 'utf-32-le'           |
|----------------------|-------------|-----------------------|

我想出了以下方法,该方法似乎可以很好地使用文件开头的字节顺序标记检测编码:

def guess_encoding_from_bom(filename, default='utf-8'):
    msboms = dict((bom['sig'], bom) for bom in (
        {'name': 'UTF-8', 'sig': b'\xEF\xBB\xBF', 'encoding': 'utf-8'},
        {'name': 'UTF-16 big-endian', 'sig': b'\xFE\xFF', 'encoding':
            'utf-16-be'},
        {'name': 'UTF-16 little-endian', 'sig': b'\xFF\xFE', 'encoding':
            'utf-16-le'},
        {'name': 'UTF-32 big-endian', 'sig': b'\x00\x00\xFE\xFF', 'encoding':
            'utf-32-be'},
        {'name': 'UTF-32 little-endian', 'sig': b'\xFF\xFE\x00\x00',
            'encoding': 'utf-32-le'}))

    with open(filename, 'rb') as f:
        sig = f.read(4)
        for sl in range(3, 0, -1):
            if sig[0:sl] in msboms:
                return msboms[sig[0:sl]]['encoding']
        return default


# Example using python csv module
def excelcsvreader(path, delimiter=',',
                doublequote=False, quotechar='"', dialect='excel',
                escapechar='\\', fileEncoding='UTF-8'):
    filepath = os.path.expanduser(path)
    fileEncoding = guess_encoding_from_bom(filepath, default=fileEncoding)
    if os.path.exists(filepath):
        # ok let's open it and parse the data
        with open(filepath, 'r', encoding=fileEncoding) as csvfile:
            csvreader = csv.DictReader(csvfile, delimiter=delimiter,
                doublequote=doublequote, quotechar=quotechar, dialect=dialect,
                escapechar='\\')
            for (rnum, row) in enumerate(csvreader):
                yield (rnum, row)

我意识到,这需要打开文件才能读取两次(一次二进制,一次为编码文本),但是在这种特殊情况下,API确实很难做到这一点。

无论如何,我认为这比简单地假设utf-8健壮得多,并且显然自动编码检测无法正常工作...

答案 2 :(得分:1)

我知道这是一个非常老的问题,但是我发现最简单的解决方案是使用NotePad ++。在NotePad ++中打开CSV文件,单击“编码”,然后选择“以UTF-8编码”并保存文件。它将删除BOM表,并且原始代码应该可以工作。

答案 3 :(得分:0)

在进一步研究之后,它与BOM(字节顺序标记)添加的字符有关。显然不能使用快速导出,而是使用数据导出向导,因为它允许设置文件编码。它适用于我的设置为西欧(Windows)而不是unicode utf-8。

请参阅How do I remove  from the beginning of a file?