我试图获得一周中的某一天,并让它在任何地方都能保持一致。在带有拉丁字母的语言环境中,一切都很好。
Sys.getlocale()
## [1] "LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=English_United Kingdom.1252"
weekdays(Sys.Date())
## [1] "Tuesday"
我与其他语言环境有两个相关问题。
如果我设置
Sys.setlocale("LC_ALL", "Arabic_Qatar")
## [1] "LC_COLLATE=Arabic_Qatar.1256;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=Arabic_Qatar.1256;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256"
然后我有时(正确地)得到
weekdays(Sys.Date())
## [1] "الثلاثاء
有时会得到
weekdays(Sys.Date())
## [1] "ÇáËáÇËÇÁ"
取决于我的设置。问题是,我无法弄清楚导致差异的原因。
我认为这可能与getOption("encoding")
有关,但我已尝试明确设置options(encoding = "native.enc")
和options(encoding = "UTF-8")
,但没有任何区别。
我已经尝试了几个最新版本的R,问题在所有版本中都是一致的。
目前,字符串在R GUI中正确显示,但在使用IDE(Architect和RStudio测试)时显示不正确。
我应该设置什么以确保工作日始终正确显示?
了解weekdays(Sys.Date())
等同于format(as.POSIXlt(Sys.Date()), "%A")
可能会有所帮助,format.POSIXlt
会调用内部weekdays
方法。
其次,改变所有语言环境似乎有些过分。我以为我应该能够设置时间选项。但是,如果我设置了区域设置的各个组件,for(category in c("LC_TIME", "LC_CTYPE", "LC_COLLATE", "LC_MONETARY"))
{
Sys.setlocale(category, "Arabic_Qatar")
print(Sys.getlocale())
print(weekdays(Sys.Date()))
}
## [1] "LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256"
## [1] "????????"
## [1] "LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256"
## [1] "????????"
## [1] "LC_COLLATE=Arabic_Qatar.1256;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256"
## [1] "????????"
## [1] "LC_COLLATE=Arabic_Qatar.1256;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=Arabic_Qatar.1256;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256"
## [1] "????????"
将返回一串问号。
"ar_QA.UTF8"
区域设置的哪些部分会影响工作日的打印方式?
更新:问题似乎与Windows有关。当我在具有区域设置Sys.setlocale("LC_TIME", "ARQ") # the language abbreviation name
Sys.setlocale("LC_TIME", "Arabic_Qatar") # corresponding to the language/country pair "Arabic (Qatar)"
Sys.setlocale("LC_TIME", "Arabic_Qatar.1256") # explicitly including the ANSI codepage
Sys.setlocale("LC_TIME", "Arabic") # would sometimes be a possibility too, but it defaults to Saudi Arabic
的Linux机器上运行代码时,会正确显示工作日。
进一步更新:正如他在答案中提到的那样,在Windows下设置区域设置很奇怪,因为你不能只使用像#34; en-GB"这样的ISO代码。对于Windows 7 / Vista / Server 2003 / XP,您可以使用setlocale language strings或National Language Support值设置区域设置。对于Qatari Arabic,没有setlocale语言字符串,因此我们必须使用NLS值。我们有几种选择:
Sys.setlocale
所以问题不在于R不能支持Windows下的阿拉伯语语言环境(尽管我并不完全相信system("wmic os set locale=MS_4001")
## Updating property(s) of '\\PC402729\ROOT\CIMV2:Win32_OperatingSystem=@'
## Property(s) update successful.
system("wmic os get locale") # same as before
的健壮性)。
绝望的最后一次尝试:尝试通过使用Windows Management Instrumentation命令来改变操作系统区域设置来神奇地解决问题,因为R似乎无法识别这些更改。
{{1}}
答案 0 :(得分:5)
命名语言环境的系统是特定于操作系统的。我建议您阅读R安装和管理手册中的locales以获得完整的解释。
在windows下列出了支持的语言列表MSDN Language Strings。令人惊讶的是,那里没有阿拉伯语。 “语言字符串”列包含用于在R 中设置区域设置的合法输入,甚至在列表contry /regions strings中也没有国家/地区使用阿拉伯语。
当然,您可以更改区域设置全局设置(面板设置 - >区域 - > ..),但这会全局更改它,并且不确定在没有编码问题的情况下获得正确的输出。
linux下的默认情况下,通常不支持阿拉伯语,但可以使用locale
轻松设置。
locale -a ## to list all already supported language
sudo locale-gen ar_QA.UTF-8 ## install it in case does not exist
现在在RStudio下:
Sys.setlocale('LC_TIME','ar_QA.UTF-8')
[1] "ar_QA.UTF-8"
> format(Sys.Date(),'%A')
[1] "الثلاثاء
另请注意,在R控制台下,打印效果不如R studio,因为它是从从左到右而不是从从右到左。
答案 1 :(得分:5)
RStudio / Architect问题
通过明确地将工作日字符串的编码更改为UTF-8,可以稍微解决这个问题。
current_codepage <- as.character(l10n_info()$codepage)
iconv(weekdays(Sys.Date()), from = current_codepage, to = "utf8")
请注意,代码页仅存在于Windows上; Linux上l10n_info()$codepage
为NULL
。
LC_TIME问题
事实证明,在Windows下,您必须同时设置LC_CTYPE
和LC_TIME
区域设置类别,并且必须在LC_CTYPE
之前设置LC_TIME
,或者它不会工作。
最后,我们需要针对不同操作系统的不同实现。
Windows版本:
get_today_windows <- function(locale = NULL)
{
if(!is.null(locale))
{
lc_ctype <- Sys.getlocale("LC_CTYPE")
lc_time <- Sys.getlocale("LC_TIME")
on.exit(Sys.setlocale("LC_CTYPE", lc_ctype))
on.exit(Sys.setlocale("LC_TIME", lc_time), add = TRUE)
Sys.setlocale("LC_CTYPE", locale)
Sys.setlocale("LC_TIME", locale)
}
today <- weekdays(Sys.Date())
current_codepage <- as.character(l10n_info()$codepage)
iconv(today, from = current_codepage, to = "utf8")
}
get_today_windows()
## [1] "Tuesday"
get_today_windows("French_France")
## [1] "mardi"
get_today_windows("Arabic_Qatar")
## [1] "الثلاثاء"
get_today_windows("Serbian (Cyrillic)")
## [1] "уторак"
get_today_windows("Chinese (Traditional)_Taiwan")
## [1] "星期二"
Linux版本:
get_today_linux <- function(locale = NULL)
{
if(!is.null(locale))
{
lc_time <- Sys.getlocale("LC_TIME")
on.exit(Sys.setlocale("LC_TIME", lc_time), add = TRUE)
Sys.setlocale("LC_TIME", locale)
}
weekdays(Sys.Date())
}
get_today_linux()
## [1] "Tuesday"
get_today_linux("fr_FR.utf8")
## [1] "mardi"
get_today_linux("ar_QA.utf8")
## [1] "الثلاثاء"
get_today_linux("sr_RS.utf8")
## [1] "уторак"
get_today_linux("zh_TW.utf8")
## [1] "週二"
在语言环境中实施.utf8
编码似乎很重要get_today_linux("zh_TW")
无法正常显示。