gtools::mixedorder搭配dplyr::arrange出现异常排序问题
原因分析
这个问题本质是对两个函数的功能理解有误导致的,核心差异如下:
gtools::mixedorder()返回的是索引向量:它的作用是给出将输入向量自然排序所需的原行位置,你的示例中mixedorder(test$V1)的返回值为c(1,9,10,11,12,13,14,15,16,2,3,4,5,6,7,8),含义是「自然排序后的第一行是原数据第1行,第二行是原数据第9行,最后一行是原数据第8行」。dplyr::arrange()的逻辑是将传入的表达式结果作为排序键,按键的大小升序排列行:你将mixedorder(V1)传入arrange时,它会把这个索引向量直接当做排序键,按每个行对应键的大小排序。
对应你的示例:原数据第9行(V1为all13_LG2的行)对应的排序键是mixedorder(V1)[9] = 16,是所有键值里最大的,所以会被排到最后,完全符合你观测到的错误结果。
而dplyr::slice()的功能就是直接按传入的索引顺序提取行,刚好匹配mixedorder()返回索引的设计,所以结果符合预期。
是否属于bug
不属于bug,是函数用法错误导致的问题。
正确实现方式
如果要用arrange实现自然排序,可选以下两种写法:
- 用
gtools::mixedrank()代替mixedorder(),mixedrank()返回的是每个元素对应的自然排序名次,刚好匹配arrange的排序逻辑:
test2 <- test %>% arrange(gtools::mixedrank(V1))
- 将V1转为因子,层级指定为自然排序后的结果:
test2 <- test %>% arrange(factor(V1, levels = gtools::mixedsort(V1)))
内容的提问来源于stack exchange,提问作者Anneke
相关产品推荐
相关产品推荐

