重新排序R data.frame中的因子级别

时间:2015-12-18 17:23:54

标签: r sorting levels

这是我所面对的一个简单例子。我的因子水平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的帮助。

2 个答案:

答案 0 :(得分:6)

我们可以将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一样。

答案 1 :(得分:1)

另一种选择,尽管IMO更糟糕,解决方案是使用本机stats::relevel功能。但是,这只允许您提供新的引用级别(请参阅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"

我主要发布此解决方案,以显示在我看来,基本R功能/解决方案中的缺陷。该功能至少名称不佳。它并没有真正的重新定位,它只是重新引用级别