gpt4 book ai didi

r - 为什么 gdata:::reorder.factor 与 stats:::reorder.default 对于整数和 double 的行为不同?

转载 作者:行者123 更新时间:2023-12-04 10:28:43 24 4
gpt4 key购买 nike

这是对 Reordering factor gives different results, depending on which packages are loaded 的跟进,还有另一个相关问题。

@Andrie的答案是正确的,并遵循 @David Lovell的评论,我因此而成为第三个困惑的灵魂。

在我的例子中,这是因为我加载了 ROCR,它依赖于 gplots,它依赖于 gdata,而我没有甚至听说过gdata,说明我无知,因此没有想到去搜索它。

我发现了另一个怪癖,这让我的案例更难解决,这就是这个问题的重点。 gdata:::reorder.factor 以不同方式处理整数和数字。举例说明:

library(gdata)
x <- factor(letters[1:6])
y <- c(1,4,3,5,6,2)
z <- c(1.1,2.4,1.3,2.5,2.6,1.2)
stats:::reorder.default(x, y, function(X)-X) #edbcfa - correct
stats:::reorder.default(x, z, function(X)-X) #edbcfa
stats:::reorder.default(x, -y) #edbcfa
stats:::reorder.default(x, -z) #edbcfa
gdata:::reorder.factor(x, y, function(X)-X) #edbcfa
gdata:::reorder.factor(x, z, function(X)-X) #bdeafc - weird
gdata:::reorder.factor(x, -y) #abcdef - no reordering
gdata:::reorder.factor(x, -z) #abcdef - no reordering

主要是我感兴趣的 bdeafc。它的小数点前的位是正确的,因为 2.x 在 1.x 之前,但小数点后的部分点按正常顺序排列,而不是倒序排列:x.1 在 x.2 在 x.3 之前。

这是为什么?

最佳答案

为什么会这样:

嗯,这似乎是因为 gdata:::reorder.factor 接受了一个名为 sort 的参数,默认情况下它的值为 mixedsort .此 mixedsort 参数使用包 gtools 中的 mixedorder 函数。通过加载 gtools 并执行 ?mixedorder,您可以找出发生这种情况的原因:

?mixedorder

Order or Sort strings with embedded numbers so that the numbers are in the correct order:

These functions sort or order character strings containing numbers so that the numbers are numerically sorted rather than sorted by character value. I.e. "Asprin 50mg" will come before "Asprin 100mg". In addition, case of character strings is ignored so that "a", will come before "B" and "C".

还有 ?reorder.factor 清楚地说明了这一点:

?gdata:::reorder.factor

If sort is provided (as it is by default): The new factor level names are generated by applying the supplied function to the existing factor level names. With sort=mixedsort the factor levels are sorted so that combined numeric and character strings are sorted in according to character rules on the character sections (including ignoring case), and the numeric rules for the numeric sections. See mixedsort for details.


解决方案:

您必须为 sort 参数提供 NULL 值,以便默认情况下不采用 mixedsort

gdata:::reorder.factor(x, z, function(X)-X, sort=NULL)
# [1] a b c d e f
# Levels: e d b c f a

或者,正如@BenBolker 在评论中指出的那样,您可以简单地提供“排序”参数 sort:

gdata:::reorder.factor(x, z, function(X)-X, sort=sort)

关于调试:

对于 future ,debugonce 是您处理这些事情的 friend 。通过做

debugonce(gdata:::reorder.factor)
gdata:::reorder.factor(x, z, function(X)-X)

(然后按回车并检查输出)您会发现问题出在正在运行的最后几行:

else if (!missing(FUN)) 
new.order <- names(sort(tapply(X, x, FUN, ...)))

对于您的数据,

> X
# [1] 1.1 2.4 1.3 2.5 2.6 1.2

> x
# [1] a b c d e f
# Levels: a b c d e f

并且,tapply(...) 给出:

> tapply(X, x, FUN, ...)
# a b c d e f
# -1.1 -2.4 -1.3 -2.5 -2.6 -1.2

在这里,“排序”应该给出:

> base:::sort(tapply(X, x, FUN, ...))
# e d b c f a
# -2.6 -2.5 -2.4 -1.3 -1.2 -1.1

但是它给出了:

#   b    d    e    a    f    c 
# -2.4 -2.5 -2.6 -1.1 -1.2 -1.3

这是因为正在调用的“sort”不是来自 base,这可以通过在调试器中键入“sort”来查看:

> sort # from within the function call (using debugonce)
# function (x)
# x[mixedorder(x)]
# <environment: namespace:gtools>

mixedorder 是包 gtools 中的一个函数。由于该命令获取 names 并且排序错误,因此获取的顺序错误。所以基本上问题是被调用的 sortmixedsort 而不是 base:::sort

通过安装 gtools 并执行以下操作很容易验证这一点:

require(gtools)
gtools:::mixedorder(c(-2.4, -2.5, -2.6))
# [1] 1 2 3

order(c(-2.4, -2.5, -2.6))
# [1] 3 2 1

因此,您必须提供 sort=NULL 以确保不会发生这种情况。

关于r - 为什么 gdata:::reorder.factor 与 stats:::reorder.default 对于整数和 double 的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20317343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com