我的数据框包含一些数值变量和一些分类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
我只想更改级别顺序,因此在绘图时,条形图按所需顺序显示 - 可能与默认的字母顺序不同。
答案 0 :(得分:109)
使用levels
的{{1}}参数:
factor
答案 1 :(得分:20)
更多,仅供记录
## 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。
答案 2 :(得分:8)
所以你想要的,在R词典中,只改变给定因子变量的 标签 (即保留数据和因子等级,不变)。
df$letters = factor(df$letters, labels=c("d", "c", "b", "a"))
假设您只想更改数据点到标签映射而不是数据或因子模式(数据点如何分组到单个箱或因子值中,可能有助于了解最初创建因子时最初如何设置映射。
规则很简单:
答案 3 :(得分:6)
处理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
正如你所看到的......通过改变等级,你只改变等级(谁会告诉,呃?),而不是数值!但是,当你使用{Jonathan Chang建议的factor
函数时,会发生一些不同的事情:你自己改变数值。
您再次收到错误,因为您执行了levels
,然后尝试使用factor
将其重新定位。不要这样做! 不使用levels
或者你会搞砸(除非你确切知道你在做什么)。
一个小的建议:避免使用与R的对象相同的名称来命名对象(df
是F分布的密度函数,letters
给出小写字母)。在这种特殊情况下,你的代码不会有问题,但有时可能会......但这会造成混乱,我们不希望这样,是吗?!? =)
的
相反,使用这样的东西(我将从头开始再次):
> 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.frame
和df
而不是letters
为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
实际上需要更改级别和值吗?嗯......我会把这个挖出来......
答案 4 :(得分:4)
由于这个问题是最后一个活跃的,Hadley已经发布了他的新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()
函数。
答案 5 :(得分:3)
我希望添加另一种情况,其中级别可以是带有数字的字符串以及一些特殊字符:如下例所示
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uhr;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
*
* @author
*/
public class UhrMain extends Application {
private VBox box;
private Button startButton;
private Button stopButton;
private Label timeLabel;
private Uhr eineUhr;
@Override
public void start(Stage primaryStage) {
eineUhr = new Uhr();
eineUhr.start();
box = new VBox();
timeLabel = new Label("Zeit: ");
startButton = new Button("Start");
//startButton.setStyle("-fx-background-color: green");
startButton.setOnAction((event) -> eineUhr.startTimer());
stopButton = new Button("Stopp");
//stopButton.setStyle("-fx-background-color: red");
stopButton.setOnAction((event) -> eineUhr.stopTimer());
box.getChildren().addAll(timeLabel,startButton,stopButton);
timeLabel.textProperty().bind(eineUhr.zeitProperty());
Scene scene = new Scene(box);
primaryStage.setScene(scene);
primaryStage.setTitle("Stoppuhr");
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
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
我希望这可以被视为未来读者的有用信息。
答案 6 :(得分:0)
这是我重新排序给定数据帧因子的函数:
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"))
答案 7 :(得分:0)
我会简单地使用 levels 参数:
levels(df$letters) <- levels(df$letters)[c(4:1)]
答案 8 :(得分:0)
添加另一种非常有用的方法,因为它使我们无需记住来自不同包的函数。因子的水平只是属性,因此可以执行以下操作:
numbers <- 1:4
letters <- factor(c("a", "b", "c", "d"))
df <- data.frame(numbers, letters)
# Original attributes
> attributes(df$letters)
$levels
[1] "a" "b" "c" "d"
$class
[1] "factor"
# Modify attributes
attr(df$letters,"levels") <- c("d", "c", "b", "a")
> df$letters
[1] d c b a
Levels: d c b a
# New attributes
> attributes(df$letters)
$levels
[1] "d" "c" "b" "a"
$class
[1] "factor"