重新排序 R data.frame 中因子的水平
Reordering levels of a factor in R data.frame
这是我所面临的一个简单示例。我有我的因子水平 B-1, B-2, B-9, B-10, B-11
并想按上面给定的顺序排列它们。在这里我可以轻松地重新排列级别,但是,在我的数据中我确实有复杂的结构并且想通过一些编码来完成。我想知道如何按逻辑顺序排列这些因素水平。
set.seed(12345)
f <- rep(c("B-1", "B-2", "B-9", "B-10", "B-11"), each=3)
Y <- runif(n=15, min=100, max=1000)
df <- data.frame(f, Y)
levels(df$f)
[1] "B-1" "B-10" "B-11" "B-2" "B-9"
library(gtools)
mixedsort(df$f)
[1] B-1 B-1 B-1 B-10 B-10 B-10 B-11 B-11 B-11 B-2 B-2 B-2 B-9 B-9 B-9
Levels: B-1 B-10 B-11 B-2 B-9
df2 <- df[mixedorder(df$f), ]
df3 <- within(df,
Position <- factor(f,
levels=names(sort(table(f),
decreasing=TRUE))))
levels(df3$Position)
[1] "B-1" "B-10" "B-11" "B-2" "B-9"
已编辑
现在我可以得到 this question 的解决方案,它在我发布后立即关闭。感谢@akrun 的帮助。
我们可以将 levels
指定为 'f' 列的 mixedsort
ed levels
。
df$f <- factor(df$f, levels=mixedsort(levels(df$f), decreasing=TRUE))
levels(df$f)
#[1] "B-1" "B-2" "B-9" "B-10" "B-11"
或者按照@Ben Bolker 的建议,一种变体是
df <- transform(df,f=factor(f,levels=mixedsort(levels(f),
decreasing=TRUE)))
我猜 -
被解释为 minus
符号,正如@Gregor 在评论中所建议的那样。
另一种方法是使用本机 stats::relevel
函数,尽管 IMO 更糟糕。但是,这只允许您提供一个新的 reference 级别(请参阅源代码的最后一行 stats:::relevel.factor
),因此您需要递归调用它。
rev_levels <- gtools::mixedsort(levels(df$f))
for (i in 1:length(rev_levels)) {
df$f <- relevel(df$f, ref= rev_levels[i])
}
levels(df$f)
[1] "B-1" "B-2" "B-9" "B-10" "B-11"
我发布这个解决方案主要是为了展示在我看来,base-R function/solution 中的一个缺陷。至少,该函数的命名很糟糕。它并没有真正重新调整,它只是重新引用级别
这是我所面临的一个简单示例。我有我的因子水平 B-1, B-2, B-9, B-10, B-11
并想按上面给定的顺序排列它们。在这里我可以轻松地重新排列级别,但是,在我的数据中我确实有复杂的结构并且想通过一些编码来完成。我想知道如何按逻辑顺序排列这些因素水平。
set.seed(12345)
f <- rep(c("B-1", "B-2", "B-9", "B-10", "B-11"), each=3)
Y <- runif(n=15, min=100, max=1000)
df <- data.frame(f, Y)
levels(df$f)
[1] "B-1" "B-10" "B-11" "B-2" "B-9"
library(gtools)
mixedsort(df$f)
[1] B-1 B-1 B-1 B-10 B-10 B-10 B-11 B-11 B-11 B-2 B-2 B-2 B-9 B-9 B-9
Levels: B-1 B-10 B-11 B-2 B-9
df2 <- df[mixedorder(df$f), ]
df3 <- within(df,
Position <- factor(f,
levels=names(sort(table(f),
decreasing=TRUE))))
levels(df3$Position)
[1] "B-1" "B-10" "B-11" "B-2" "B-9"
已编辑
现在我可以得到 this question 的解决方案,它在我发布后立即关闭。感谢@akrun 的帮助。
我们可以将 levels
指定为 'f' 列的 mixedsort
ed levels
。
df$f <- factor(df$f, levels=mixedsort(levels(df$f), decreasing=TRUE))
levels(df$f)
#[1] "B-1" "B-2" "B-9" "B-10" "B-11"
或者按照@Ben Bolker 的建议,一种变体是
df <- transform(df,f=factor(f,levels=mixedsort(levels(f),
decreasing=TRUE)))
我猜 -
被解释为 minus
符号,正如@Gregor 在评论中所建议的那样。
另一种方法是使用本机 stats::relevel
函数,尽管 IMO 更糟糕。但是,这只允许您提供一个新的 reference 级别(请参阅源代码的最后一行 stats:::relevel.factor
),因此您需要递归调用它。
rev_levels <- gtools::mixedsort(levels(df$f))
for (i in 1:length(rev_levels)) {
df$f <- relevel(df$f, ref= rev_levels[i])
}
levels(df$f)
[1] "B-1" "B-2" "B-9" "B-10" "B-11"
我发布这个解决方案主要是为了展示在我看来,base-R function/solution 中的一个缺陷。至少,该函数的命名很糟糕。它并没有真正重新调整,它只是重新引用级别