当您的包包含具有非英文字符的函数时出现编码问题

Encoding problem when your package contains functions with non-english characters

我正在构建自己的程序包,并且 运行一直在处理编码问题,因为我的程序包中的函数具有非英语(非 ASCII)字符。

本质上,韩文字符是我包中许多功能的一部分。示例函数:

library(rvest)
sampleprob <- function(url) {
  # sample url: "http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20200330003851"
  result <- grepl("연결재무제표 주석", html_text(read_html(url)))
  return(result)
}

但是我在安装包的时候运行遇到了编码问题。

我创建了一个只有一个功能(如上所示)的示例包 (https://github.com/hyk0127/KorEncod/),并将其上传到我的 github 页面以获取可重现的示例。我运行安装以下代码:

library(devtools)
install_github("hyk0127/KorEncod")

下面是我看到的错误信息

Error : (converted from warning) unable to re-encode 'hello.R' line 7
ERROR: unable to collate and parse R files for package 'KorEncod'
* removing 'C:/Users/myname/Documents/R/win-library/3.6/KorEncod'
* restoring previous 'C:/Users/myname/Documents/R/win-library/3.6/KorEncod'
Error: Failed to install 'KorEncod' from GitHub:
  (converted from warning) installation of package ‘C:/Users/myname/AppData/Local/Temp/RtmpmS5ZOe/file48c02d205c44/KorEncod_0.1.0.tar.gz’ had non-zero exit status

关于line 7的错误信息是指函数中的韩文字符。

可以使用 tar.gz 文件在本地安装程序包,但此功能无法按预期 运行,因为韩文字符在损坏的编码中被识别。

这不是第一次有人尝试构建具有非英语(或非 ASCII)字符的包,但我找不到解决方案。任何帮助将不胜感激。


我认为相关的几条信息:

当前 DESCRIPTION 文件指定“编码:UTF-8”。

我已经使用 sys.setlocale 将语言环境设置为韩语,但没有成功。 我已经为函数指定了 @encoding UTF-8 也无济于事。

我目前正在使用 Windows,其中管理语言设置为英语。我尝试使用另一台笔记本电脑,并将 Windows 和管理语言设置为韩语,但出现了同样的问题。

关键技巧是用它们的 unicode 代码替换非 ASCII 字符 - \uxxxx 编码。

这些可以通过 stringi::stri_escape_unicode() 函数生成。

请注意,由于必须完全删除代码中的韩文字符才能通过 R CMD 检查,因此必须通过 {stringi} 执行手动复制和重新编码在命令行上对包中包含的所有 R 脚本执行回贴操作。

我不知道这个问题有可用的自动化解决方案。

在示例的特定用例中,提供的 unicode 将如下所示:

sampleprob <- function(url) {
  # stringi::stri_escape_unicode("연결재무제표 주석") to get the \uxxxx codes
  result <- grepl("\uc5f0\uacb0\uc7ac\ubb34\uc81c\ud45c \uc8fc\uc11d", 
                  rvest::html_text(xml2::read_html(url)))
  return(result)
}
sampleprob("http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20200330003851")
[1] TRUE

这会很麻烦,但这似乎是使您的代码平台中立的唯一方法(这是关键的 CRAN 要求,因此需要接受 R CMD 检查)。

添加未来的价值(对于那些面临类似问题的人),您也可以通过将非ASCII字符保存在数据文件中,然后加载该值并使用它来解决这个问题。

因此将角色保存为数据文件(使用标准包文件夹名称和 roxygen2 包)

# In your package, save as a separate file within .\data-raw 
kor_chrs <- list(sampleprob = "연결재무제표 주석")
usethis::use_data(kor_chrs)

然后在您的函数中加载数据并使用它们。

# This is your R file for the function within ./R folder
#' @importFrom rvest html_text
#' @importFrom xml2  read_html
#' @export
sampleprob <- function(url) {
  # sample url: "http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20200330003851"
  result <- grepl(kor_chrs$sampleprob[1], html_text(read_html(url)))
  return(result)
}

这仍然是一种解决方法,但它可以在 Windows 台机器上运行,没有任何问题。