如何让R的DataFrame排序匹配Python的ASCII排序规则?
问题
在使用R对DataFrame排序时,发现其大小写敏感排序的顺序不符合标准ASCII规则(大写字母应排在小写字母之前),和Python的排序行为不一致。
当前使用的R排序代码:
df = df[do.call(order, df), ] # 按所有列排序
Python中的排序行为(符合ASCII规则):
$ python Python 3.7.12 | packaged by conda-forge | (default, Oct 26 2021, 06:08:53) >>> "A" < "a" True
R中的排序行为(不符合ASCII规则):
$ R R version 3.2.0 (2015-04-16) -- "Full of Ingredients" Copyright (C) 2015 The R Foundation for Statistical Computing Platform: x86_64-unknown-linux-gnu (64-bit) Natural language support but running in an English locale > "A" < "a" [1] FALSE > "A" > "a" [1] TRUE
需要修改R的排序行为以匹配标准ASCII排序,询问是否有order函数的参数或配置设置可以更改排序顺序。
注:这并非大小写敏感与不敏感排序的区别,而是大小写敏感排序的顺序不符合标准。
解决方案
方法1:修改全局locale设置
R的字符串排序默认依赖系统locale,多数英文locale(如en_US.UTF-8)采用字典序而非纯ASCII序。可以通过将LC_COLLATE locale设置为C,强制使用ASCII排序规则:
# 临时切换到C locale,仅影响当前会话 Sys.setlocale(category = "LC_COLLATE", locale = "C") # 执行原排序代码 df = df[do.call(order, df), ]
如果需要恢复原有locale,可先保存原设置再切换:
original_locale = Sys.getlocale("LC_COLLATE") Sys.setlocale("LC_COLLATE", "C") # 执行排序操作 Sys.setlocale("LC_COLLATE", original_locale) # 恢复原locale
方法2:自定义排序键(不修改全局设置)
若不想改变全局locale,可为字符列生成基于ASCII码的排序键,再基于这些键排序:
# 为每列生成适配ASCII排序的键 sort_keys = lapply(df, function(col) { if (is.character(col)) { # 将字符串转换为ASCII码数值组合,生成唯一排序标识 sapply(col, function(s) { ints = utf8ToInt(s) sum(ints * 256^(rev(seq_along(ints)) - 1)) }) } else { col # 非字符列直接使用原列值 } }) # 基于自定义键排序DataFrame df = df[do.call(order, sort_keys), ]
此方法仅作用于当前排序操作,不会影响其他代码的排序逻辑。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

