在 R、Rmd、knitr 和 bookdown 中打印 UTF-8 字符

5

更新(2018年4月):
问题仍然存在,出现在不同的设置和计算机上。 我认为这与所有UNICODE、UTF-8字符有关。

https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/

问题:

我的Rmd/R文件以UTF-8编码保存。其他sessionInfo()细节:

Platform: x86_64-w64-mingw32/x64 (64-bit)
LC_CTYPE=English_Canada.1252

other attached packages:
[1] knitr_1.17

这里有一个简单的数据框,我需要将其作为表格打印在HTML文档中,例如使用kable(dt)或其他方式。

dt <- data.frame(
name=c("Борис Немцов","Martin Luter King"),
year=c("2015","1968") 
)

以下两种方法都无法解决问题:

方法一

如果我保持Sys.setlocale()不变(即"English_Canada.1252"),那么我会得到这个结果:

> dt;                                                                                           
name year
1 <U+0411><U+043E><U+0440><U+0438><U+0441> <U+041D><U+0435><U+043C><U+0446><U+043E><U+0432> 2015
2 Martin Luter King 1968
> kable(dt)
|name                                                                                      |year |
|:-----------------------------------------------------------------------------------------|:----|
|<U+0411><U+043E><U+0440><U+0438><U+0441> <U+041D><U+0435><U+043C><U+0446><U+043E><U+0432> |2015 |
|Martin Luter King                                                                         |1968 |

请注意,字符将被打印为<U+....>。使用dt$name <- enc2utf8(as.character(dt$name))并没有帮助。
方法2: 如果我更改Sys.setlocale("LC_CTYPE", "russian") #"Russian_Russia.1251",那么我会得到这个结果:
> dt; 
name year
1      Áîðèñ Íåìöîâ 2015
2 Martin Luter King 1968

> kable(dt)
|name              |year |
|:-----------------|:----|
|Áîðèñ Íåìöîâ      |2015 |
|Martin Luter King |1968 |

请注意,字符变成了乱码。
使用print(dt,encoding="windows-1251"); print(dt,encoding="UTF-8")没有效果。

有什么建议吗?

我能找到的最接近解决此问题的链接如下,但它们没有帮助:http://blog.rolffredheim.com/2013/01/r-and-foreign-characters.htmlhttps://tomizonor.wordpress.com/2013/04/17/file-utf8-windowshttps://www.smashingmagazine.com/2012/06/all-about-unicode-utf8-character-sets

我还尝试将文件保存为1251编码(而不是当前的UTF-8编码)和其他字符转换/处理包。目前仍然没有帮助。

更新:

打开相关问题:当你收到错误“请求设置区域设置......不能被授予”时如何更改Sys.setlocale


在控制台打印或编织HTML文档时,我使用本地语言环境en_US.UTF-8没有问题。但是使用LaTeX就不一样了。 - Martin Schmelzer
谢谢您的尝试 - 我尝试将我的语言环境设置为您所拥有的 Sys.setlocale("LC_CTYPE", "en_US.UTF-8"),但是出现了以下错误:OS reports request to set locale to "en_US.UTF-8" cannot be honored[1] ""。这可能解释了为什么它对您有效,但对我无效(我的本地环境是 LC_CTYPE=English_Canada.1252)。那我该怎么办呢? - IVIM
我从knitr开发者那里找到了两个相关的建议:https://dev59.com/zHDXa4cB1Zd3GeqP-kk1和https://dev59.com/MIbca4cB1Zd3GeqPcvcN。这个想法是将UTF-8代码放在一个单独的文件中,然后从那里读取它:`con = file("TestSpanishText.R", encoding = "UTF-8");read_chunk(con);close(con)` - - IVIM
1
你可以尝试在你的~/.Rprofile中设置Sys.setlocale(, "Russian")吗?如果你不知道什么是.Rprofile,你可以参考https://bookdown.org/yihui/blogdown/global-options.html - Yihui Xie
太棒了!- 我这样做并使用 print(dt) 打印仍然显示相同的乱码,但是使用 kable(dt) 打印出了所需的内容!因此结论是 - 放置 Sys.setlocale("LC_CTYPE", "russian") 是不够的。您必须将其放在 .Rprofile 中,而且它只适用于 kable()(感谢 knitr 开发人员 :) - IVIM
1个回答

1
唯一有效的解决方案是由Yihui Xie(knitr开发者)提出的建议:
创建一个文件.Rprofile,其中包含一行代码Sys.setlocale("LC_CTYPE", "russian"),并将其放置在您的主目录或工作目录中。
但请注意,它仅适用于使用kable(),即使用knitr软件包的情况下。
如果您尝试使用print(dt$name[1])打印,您仍然会得到Áîðèñ Íåìöîâ。
但是,如果您使用kable(dt$name[1]),您将获得所需的结果- Борис Немцов!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接