重新排序因子水平没有改变值的顺序重新排序因子水平没有改变值的顺序(Reorder levels of

2019-05-09 04:58发布

我有一些数值变量和一些分类数据帧factor变量。 水平对这些因素的顺序不是我希望他们的方式。

numbers <- 1:4
letters <- factor(c("a", "b", "c", "d"))
df <- data.frame(numbers, letters)
df
#   numbers letters
# 1       1       a
# 2       2       b
# 3       3       c
# 4       4       d

如果我改变级别的顺序,字母不再与它们对应的号码(我的数据是从这个角度上总废话)。

levels(df$letters) <- c("d", "c", "b", "a")
df
#   numbers letters
# 1       1       d
# 2       2       c
# 3       3       b
# 4       4       a

我只是想改变等级顺序,因此打印时,该酒吧在期望的顺序显示-这可以从默认的字母顺序不同。

Answer 1:

使用levels的说法factor

df <- data.frame(f = 1:4, g = letters[1:4])
df
#   f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d

levels(df$g)
# [1] "a" "b" "c" "d"

df$g <- factor(df$g, levels = letters[4:1])
# levels(df$g)
# [1] "d" "c" "b" "a"

df
#   f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d


Answer 2:

一些更多的,仅仅是为了记录

## reorder is a base function
df$letters <- reorder(df$letters, new.order=letters[4:1])

library(gdata)
df$letters <- reorder.factor(df$letters, letters[4:1])

您也可以找到有用的Relevel和combine_factor 。



Answer 3:

所以你想要什么,R中的词汇,是只改变标签对于给定的因子变量(即,保留数据以及因子水平 ,不变)。

df$letters = factor(df$letters, labels=c("d", "c", "b", "a"))

给你想要的数据点是如何分级成单独的垃圾箱或因子值仅更改数据点到标签映射 ,而不是数据或因素的架构(,它可能有助于了解如何映射最初的设置在最初创建因素。

规则很简单:

  • 标签由索引值映射到水平(即,在水平的值[2]被赋予标签,标签[2]);
  • 因子水平可以显式地在将它们通过水平参数进行设置; 要么
  • 如果没有值的水平参数提供,则使用默认值是的结果调用在(用于数据参数)传递的数据矢量是唯一的 ;
  • 标签可以明确地通过标签参数进行设置; 要么
  • 如果没有值为标签参数提供,则使用默认值这仅仅是水平向量


Answer 4:

与R中因素的处理是相当奇特的工作,我必须承认......虽然重新排序因子水平,你不会重新排序底层的数值。 这里有一个小演示:

> numbers = 1:4
> letters = factor(letters[1:4])
> dtf <- data.frame(numbers, letters)
> dtf
  numbers letters
1       1       a
2       2       b
3       3       c
4       4       d
> sapply(dtf, class)
  numbers   letters 
"integer"  "factor" 

现在,如果你转换这个因素为数字,你会得到:

# return underlying numerical values
1> with(dtf, as.numeric(letters))
[1] 1 2 3 4
# change levels
1> levels(dtf$letters) <- letters[4:1]
1> dtf
  numbers letters
1       1       d
2       2       c
3       3       b
4       4       a
# return numerical values once again
1> with(dtf, as.numeric(letters))
[1] 1 2 3 4

你可以通过改变水平看......,你改变水平只(谁知道,对吧?),而不是数值! 但是,当你使用factor的功能@Jonathan昌建议,不同的东西发生了:你改变数值本身。

你再次得到错误,因为你做的levels ,然后试图用relevel它factor 。 不要做它! 不要使用levels ,否则会搞乱了(除非你知道自己在做什么)。

相反,使用这样的事情(我会从再次开始去):

> dtf <- data.frame(f = 1:4, g = factor(letters[1:4]))
> dtf
  f g
1 1 a
2 2 b
3 3 c
4 4 d
> with(dtf, as.numeric(g))
[1] 1 2 3 4
> dtf$g <- factor(dtf$g, levels = letters[4:1])
> dtf
  f g
1 1 a
2 2 b
3 3 c
4 4 d
> with(dtf, as.numeric(g))
[1] 4 3 2 1

请注意,您也可以命名你data.framedfletters ,而不是g ,其结果将是确定。 其实,这个代码与您发布的一个,只有名称被更改相同。 这部分factor(dtf$letter, levels = letters[4:1])将不会引发错误,但它可以混淆!

阅读?factor彻底手册! 什么之间的差异factor(g, levels = letters[4:1])factor(g, labels = letters[4:1]) 什么是在相似levels(g) <- letters[4:1]g <- factor(g, labels = letters[4:1])

你可以把ggplot语法,所以我们可以帮助您更在这一个!

干杯!!!

编辑:

ggplot2实际上需要改变这两个层面和价值观? 嗯......我会来挖这一个...



Answer 5:

由于这个问题是最后一个活动哈德利已经发布了他的新forcats包操纵的因素,我发现它悍然有用。 从OP的数据帧的例子:

levels(df$letters)
# [1] "a" "b" "c" "d"

为扭转水平:

library(forcats)
fct_rev(df$letters) %>% levels
# [1] "d" "c" "b" "a"

要添加更多的级别:

fct_expand(df$letters, "e") %>% levels
# [1] "a" "b" "c" "d" "e"

还有更多有用fct_xxx()函数。



Answer 6:

我想增加一个情况下的水平可能是字符串携带数字非常久远的一些特殊字符:如下面例子

df <- data.frame(x = c("15-25", "0-4", "5-10", "11-14", "100+"))

默认级别x是:

df$x
# [1] 15-25 0-4   5-10  11-14 100+ 
# Levels: 0-4 100+ 11-14 15-25 5-10

在这里,如果我们想根据数值重新排序因子水平,没有明确地写出来的水平,我们可以做什么

library(gtools)
df$x <- factor(df$x, levels = mixedsort(df$x))

df$x
# [1] 15-25 0-4   5-10  11-14 100+ 
# Levels: 0-4 5-10 11-14 15-25 100+
as.numeric(df$x)
# [1] 4 1 2 3 5

我希望这可以看作是对未来的读者有用的信息。



Answer 7:

这里是我的功能重新安排一个给定的数据帧的因素:

reorderFactors <- function(df, column = "my_column_name", 
                           desired_level_order = c("fac1", "fac2", "fac3")) {

  x = df[[column]]
  lvls_src = levels(x) 

  idxs_target <- vector(mode="numeric", length=0)
  for (target in desired_level_order) {
    idxs_target <- c(idxs_target, which(lvls_src == target))
  }

  x_new <- factor(x,levels(x)[idxs_target])

  df[[column]] <- x_new

  return (df)
}

用法: reorderFactors(df, "my_col", desired_level_order = c("how","I","want"))



文章来源: Reorder levels of a factor without changing order of values
标签: r levels