144

いくつかの数値変数といくつかのカテゴリ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

レベルの順序を変更したいだけなので、プロットすると、バーは目的の順序で表示されます。これは、デフォルトのアルファベット順とは異なる場合があります。

4

9 に答える 9

138

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
于 2010-03-03T23:34:53.270 に答える
24

もう少し、記録のために

## 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])

また、便利なRelevelcombine_factorを見つけることもできます。

于 2010-03-04T11:10:58.543 に答える
13

この質問が最後にアクティブだったので、ハドリーは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()機能。

于 2016-10-12T22:08:22.410 に答える
11

したがって、Rレキシコンで必要なのは、特定の因子変数のラベルのみを変更することです(つまり、データと因子レベルを変更せずに残します)。

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

データまたはファクタースキーマ(データポイントが個々のビンまたはファクター値にビニングされる方法)ではなく、データポイントからラベルへのマッピングのみを変更する場合、最初に作成するときにマッピングが最初にどのように設定されているかを知ることが役立つ場合があります要因。

ルールは単純です:

  • ラベルはインデックス値によってレベルにマップされます(つまり、levels[2]の値にはlabel[2]というラベルが付けられます)。
  • 因子レベルは、 levels引数を介して渡すことで明示的に設定でき ます。また
  • レベル引数に値が指定されていない場合は、デフォルト値が使用されます。これは、 (データ引数に対して)渡されたデータベクトルでuniqueを呼び出す結果です。
  • ラベルは、labels引数を介して明示的に設定できます。また
  • labels引数に値が指定されていない場合は、レベルベクトルのみであるデフォルト値が使用されます。
于 2010-03-03T22:55:15.583 に答える
7

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 Changが提案したように関数を使用すると、別のことが起こります。数値自体を変更します。

もう一度エラーが発生します。これは、エラーを発生させてlevelsから、で再レベル化しようとするためfactorです。しないでください!!! 使用しないでください。使用しないlevelsと、物事が台無しになります(自分が何をしているかを正確に理解していない限り)。

1つのlilの提案:Rのオブジェクトと同じ名前でオブジェクトに名前を付けることは避けてください(dfF分布の密度関数であり、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して名前を付けることもでき、結果はOKになることに注意してください。実際、このコードはあなたが投稿したものと同じですが、名前だけが変更されています。この部分はエラーをスローしませんが、混乱する可能性があります。dflettersgfactor(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実際にレベルと値の両方を変更する必要がありますか?うーん...これを掘り出します...

于 2010-03-04T12:19:15.960 に答える
3

レベルがいくつかの特殊文字と一緒に数字を運ぶ文字列である可能性がある別のケースを追加したいと思います:以下の例のように

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

これが将来の読者にとって有用な情報と考えられることを願っています。

于 2017-01-24T14:54:22.357 に答える
1

私は単にlevels引数を使用します:

levels(df$letters) <- levels(df$letters)[c(4:1)]
于 2021-01-29T10:15:37.563 に答える
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"))

于 2018-04-07T15:00:37.743 に答える
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"
于 2021-05-29T18:24:22.347 に答える