Unicode不等号在Windows环境中的R中变成等号

Posted

技术标签:

【中文标题】Unicode不等号在Windows环境中的R中变成等号【英文标题】:Unicode inequality signs become equal sign in R in Windows environment 【发布时间】:2021-04-26 19:55:26 【问题描述】:

这听起来像一个简单的问题,但我无法以某种方式解决它。我想打印一个数据框,最好使用knitr::kable() 函数,该数据框包含一个字符串,该字符串在 R 中具有“大于或等于符号”(或相反的符号),但该符号被转换为“等于 (=) ' 打印时签名。我将首先向您展示问题,然后再向您展示我已经尝试找到答案的方法。

library(knitr)
minimal.example <- data.frame(x= "≥10",y="≤20")
# note: same results with data.frame(x="\U2265 10", y="\U2264 20")
knitr::kable(minimal.example)

输出:

x y
=10 =20

预期输出:

x y
≥10 ≤20

我从here 和here 的答案中知道,这个问题发生在普通 R 以及 Rstudio 中,并且在安装在 Windows 下的 R 中;因此它不能在 MAC 或 Linux 操作系统上重现。使用expression() 函数提出here 的建议在我的情况下不起作用,可能是因为我的Windows 机器?基本 R 打印函数 print(minimal.example) 也会出现此问题,因此它不限于 kable() 函数。 我已将我的 R 版本更新到最新版本,但结果仍然相同。我还尝试了不同的语言环境 (Dutch_Netherlands.1252),其他人尝试了美国语言环境但没有效果。

两个问题:

    有人可以解释发生了什么吗? (我的猜测是它发生在基础 R data.frame 函数中?) 如何解决此问题以获得所需的结果?我需要能够在 Rmarkdown 文档中将它同时转换为 latex 和 html(kable 函数通常没有问题)。

非常感谢任何帮助!

会话信息:

R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)

Matrix products: default

locale:
[1] LC_COLLATE=English_United Kingdom.1252  LC_CTYPE=English_United Kingdom.1252    LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C                            LC_TIME=English_United Kingdom.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] knitr_1.30

loaded via a namespace (and not attached):
[1] compiler_4.0.3 tools_4.0.3    highr_0.8      xfun_0.19    

【问题讨论】:

Windows-1252(您的语言环境编码)没有不等式符号。这可能是在其他操作系统中您看不到问题的原因(其他操作系统默认使用 UTF-8)。因此,请检查如何在 UTF-8 中设置 R 的终端和 OUTPUT(以及以也可以显示输出的方式 感谢您的回复。我搜索了将语言环境更改为 UTF-8;也许这在 Windows 下是不可能的?例如,参见here。 Rstudio 中的默认文本编码设置为 UTF-8,但问题仍然存在。 您的代码与 locales &lt;- c("LC_COLLATE","LC_CTYPE","LC_MONETARY","LC_NUMERIC","LC_TIME"); for (x in locales) Sys.setlocale(category = x, locale="English_United Kingdom.437") 一起工作(我知道,CP437 可能会因更复杂的数据而失败)。 CP437 比 1252 最差。Windows 能够使用 UTF-8,许多终端都可以做到。我认为 R FAW 对此有所了解(关于如何设置)。你应该把它放在启动 R 之前(所以在终端中,或者在将启动 R 的 .bat 文件中 显然,截至 2020 年 7 月,在 Windows 上对 R 的 UTF-8 支持仍处于试验阶段:Windows/UTF-8 Build of R and CRAN Packages 【参考方案1】:

所以,基于我上面问题的 cmets:我认为在 Windows 下支持 R 中的 UTF-8 支持之前(see here),这个问题仍然会出现,没有一般的解决方案,我们必须解决这个问题.

@JosefZ 提出的解决方法 1:您可以尝试使用具有我需要的特殊符号的 CP437 编码,使用 Sys.setlocale 函数 (English_United Kingdom.437)。缺点是:它对其他特殊字符的限制更大,因此并非在所有情况下都有效。查看here支持哪些字符

解决方法 2:使用正则表达式将符号替换为等效的乳胶似乎在特定情况下有效,尤其适用于 knitr::kable() 表。虽然有点长,字符也应该用美元符号括起来,例如$\\\\leq$。此外,小标题在正常的基本 R 数据帧中工作得更好。注意:此解决方案在使用tibble(x="≥10",y="≤20") 时不起作用,仅在使用tibble(x="\U2265 10", y="\U2264 20") 时起作用。当您阅读带有任何readrread_excel 函数的表格时,它似乎可以工作,这就是我需要使用它的方式。

library(knitr)
library(dplyr)
library(stringr)

minimal.example <- dplyr::tibble(x="\U2265 10", y="\U2264 20")
adjusted.data <- minimal.example %>% 
  mutate(across(everything(), ~str_replace_all(., "\U2264", "\\\\leq")
                )) %>% 
  mutate(across(everything(), ~str_replace_all(., "\U2265", "\\\\geq")
  )) %>% 
  mutate(across(everything(), 
                ~ifelse(
                  str_detect(., "\\\\leq|\\\\geq"),
                  trimws(paste0("$", ., "$")),
                  .
                  )
                )
         )

knitr::kable(adjusted.data)

这会给出下面的 html 表格作为输出,并在 (R)markdown 环境中正确呈现:

<table>
 <thead>
  <tr>
   <th style="text-align:left;"> x </th>
   <th style="text-align:left;"> y </th>
  </tr>
 </thead>
<tbody>
  <tr>
   <td style="text-align:left;"> $\geq 10$ </td>
   <td style="text-align:left;"> $\leq 20$ </td>
  </tr>
</tbody>
</table>

非常感谢任何改进或更好的答案。

【讨论】:

以上是关于Unicode不等号在Windows环境中的R中变成等号的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中的 glutIdleFunc() 中变量值未递增

将POSIX时间分配给R中的不等间隔

Windows 记事本的 ANSI,Unicode,UTF-8 这三种编码模式有啥区别

Windows 中的 Unicode 规范化

具有相等和不等式的回归约束了R中的系数

mingw64位,win764位如何安装,环境变量?