使用RPostgreSQL的UTF-8/Unicode文本编码

Dav*_*d L 15 postgresql encoding r utf-8 rpostgresql

我在Windows机器上运行R,它直接链接到PostgreSQL数据库.我没有使用RODBC.我的数据库以UTF-8编码,由以下R命令确认:

dbGetQuery(con, "SHOW CLIENT_ENCODING")
#   client_encoding
# 1            UTF8
Run Code Online (Sandbox Code Playgroud)

但是,当一些文本被读入R时,它在R中显示为奇怪的文本.

例如,我的PostgreSQL数据库中显示以下文本:"Stéphane"

出口至R之后它表现为:"STA©PHANE"(该é被编码为é)

导入RI时,使用dbConnect命令建立连接,dbGetQuery使用SQL查询数据的命令.连接到数据库或运行查询时,我没有在任何地方指定任何文本编码.

我在网上搜索过,找不到直接解决我的问题的方法.我找到了这个链接,但他们的问题是RODBC,我没有使用.

此链接有助于识别符号,但我不只是想在R ...中查找和替换太多数据.

我确实尝试在下面运行以下命令,然后发出警告.

Sys.setlocale("LC_ALL", "en_US.UTF-8")
# [1] ""
# Warning message:
# In Sys.setlocale("LC_ALL", "en_US.UTF-8") :
#   OS reports request to set locale to "en_US.UTF-8" cannot be honored
Sys.setenv(LANG="en_US.UTF-8")
Sys.setenv(LC_CTYPE="UTF-8")
Run Code Online (Sandbox Code Playgroud)

警告发生在Sys.setlocale("LC_ALL", "en_US.UTF-8")命令上.我的直觉是这是Windows特定的问题,并且在Mac/Linux/Unix中不会发生.

Cra*_*ger 13

导出到R之后显示为:"Stéphane"(é编码为é)

您的R环境使用的是1字节非组合编码,如latin-1或windows-1252.在Python中见证这个测试,证明utf-8字节é,如同它们是latin-1那样被解码,产生你看到的文本:

>>> print u"é".encode("utf-8").decode("latin-1")
é
Run Code Online (Sandbox Code Playgroud)

无论是SET client_encoding = 'windows-1252'或固定编码的[R环境使用.如果它在cmd.exe控制台中运行,你需要搞乱chcp控制台命令; 否则它特定于你的R运行时.

  • @DavidL请注意,如果采用该方法,并且您的数据包含无法在Windows-1252中表示的字符,则查询将因编码错误而失败.如果可能的话,使用Unicode来改变您的R环境会更好*. (4认同)
  • 这是有效的.我在从PostgreSQL加载数据之前运行了命令`postgresqlpqExec(con,"SET client_encoding ='windows-1252'")`,即使系统返回"FALSE",它仍然会转换为所需的字符.谢谢! (2认同)
  • 如何使用Unicode设置R环境? (2认同)

Sca*_*bee 7

正如Craig Ringer所说,设置client_encoding为windows-1252可能不是最好的选择.实际上,如果您检索的数据包含一个异国情调的角色,那么您就遇到了麻烦:

postgresqlExecStatement(conn,statement,...)出错:RS-DBI驱动程序:(无法检索结果:ERROR:编码"UTF8"的字符0xcca7在"WIN1252"中没有等效项)

另一方面,让你的R环境使用Unicode是不可能的(我和你有同样的问题Sys.setlocale......在这个问题中也是如此.).

解决方法是使用如下函数手动声明所有数据的UTF-8编码:

set_utf8 <- function(x) {
  # Declare UTF-8 encoding on all character columns:
  chr <- sapply(x, is.character)
  x[, chr] <- lapply(x[, chr, drop = FALSE], `Encoding<-`, "UTF-8")
  # Same on column names:
  Encoding(names(x)) <- "UTF-8"
  x
}
Run Code Online (Sandbox Code Playgroud)

您必须在所有查询中使用此功能:

set_utf8(dbGetQuery(con, "SELECT myvar FROM mytable"))
Run Code Online (Sandbox Code Playgroud)

编辑:另一种可能性是使用RPostgres而不是RPostgreSQL.我测试了它(使用与你的问题相同的配置),并且据我所知,所有声明的编码都自动设置为UTF-8.

  • 我可以确认使用RPostgres解决了这个问题. (2认同)