2

我在以下问题中尝试了该方法,但仍然被卡住。

如何检测 read.csv 的正确编码?

以下代码应该是可复制的......有什么想法吗?我宁愿不使用 scan() 或 readLines,因为我过去一直成功地将此代码用于各种状态级 ACS 数据......

我的另一个想法是在导入之前编辑文本文件。但是,我存储压缩文件并使用脚本解压缩然后访问数据。不得不在 R 环境之外编辑文件真的会搞砸这个过程。提前致谢!

Filename <- "g20095us.txt"
Url <- "http://www2.census.gov/acs2005_2009_5yr/summaryfile/2005-2009_ACSSF_By_State_By_Sequence_Table_Subset/UnitedStates/All_Geographies_Not_Tracts_Block_Groups/"

Widths <- c(6,2,3,2,7,1,1,1,2,2,3,5,5,6,1,5,4,5,1,3,5,5,5,3,5,1,1,5,3,5,5,5,2,3,
        3,6,3,5,5,5,5,5,1,1,6,5,5,40,200,6,1,50)
Classes <- c(rep('character',4),'integer',rep('character',47))
Names <- c('fileid','stusab','sumlev','geocomp','logrecno','us','region','division',
       'statece','state','county','cousub','place','tract','blkgrp','concit',
       rep('blank',14),'ua',rep('blank',11),'ur',rep('blank',4),'geoid','name',rep('blank',3))
GeoHeader <- read.fwf(paste0(Url,Filename),widths=Widths,
                  colClasses=Classes,col.names=Names,fill=TRUE,strip.white=TRUE)

下面文件“g2009us.txt”中的四行。第二个“Canoncito”引起了问题。下载中的其他文件是 csv,但这个是固定宽度的,并且是识别感兴趣的地理所必需的(数据的组织不是很直观)。

ACCSF US251000000964 2430 090 25100US2430090 卡梅伦章,纳瓦霍民族保留和非保留信托土地,亚利桑那州--NM--UT ACSF US251000000966 2430 095 25100US2430095 卡萨梅罗湖分会,Navajo Nation Reservation and Off-Reservation Trust Land, AZ--NM--UT ACCSF US251000000967 2430 105 25100US2430105 Chi Chil Tah Chapter, Navajo Nation Reservation and Off-Reservation Trust Land, AZ--NM--UT

4

1 回答 1

8

首先,我们首先识别所有非 ASCII 字符。为此,我将其转换为原始向量,然后查找超过 127 的值(ASCII 中最后一个明确编码的值)。

lines <- readLines("g20095us.txt")

non_ascii <- function(x) {
  any(charToRaw(x) > 127)
}

bad <- vapply(lines, non_ascii, logical(1), USE.NAMES = FALSE)
lines[bad]

然后我们需要弄清楚正确的编码是什么。当我们只有两个案例时,这是具有挑战性的,并且经常涉及一些试验和错误。在这种情况下,我用谷歌搜索“encoding \xf1”,并发现 为什么这种转换为 utf8 不起作用?,这表明 latin1 可能是正确的编码。

我测试了使用iconvwhich 从一种编码转换为另一种编码(并且您总是想使用 utf-8):

iconv(lines[bad], "latin1", "utf-8")

最后,我们使用正确的编码重新加载。令人困惑的是,任何read.*函数的编码参数都不会这样做 - 您需要在连接上手动指定编码:

fixed <- readLines(file("g20095us.txt", encoding = "latin1"))
fixed[bad]
于 2012-11-21T22:51:40.817 回答