サーチ…


構文

  1. 因子(x = character()、レベル、ラベル=レベル、除外= NA、順序付け= is.ordered(x)、nmax = NA)
  2. ?factor実行する?factorオンラインでドキュメントを参照してください

備考

クラスfactor持つオブジェクトは、特定の特性セットを持つベクトルです。

  1. 内部的にintegerベクトルとして格納されます。
  2. これは、値の文字表現を示すlevels属性を保持します。
  3. そのクラスはfactorとして格納されます

説明するために、一連の色から1000個の観測ベクトルを生成しましょう。

set.seed(1)
Color <- sample(x = c("Red", "Blue", "Green", "Yellow"), 
                size = 1000, 
                replace = TRUE)
Color <- factor(Color)

上記のColor各特性を見ることができます:

#* 1. It is stored internally as an `integer` vector
typeof(Color)
[1] "integer"
#* 2. It maintains a `levels` attribute the shows the character representation of the values.
#* 3. Its class is stored as `factor`
attributes(Color)
$levels
[1] "Blue"   "Green"  "Red"    "Yellow"

$class
[1] "factor"

ファクタオブジェクトの主な利点は、データストレージの効率です。整数は文字よりも記憶に必要なメモリが少なくて済みます。このような効率性は、多くのコンピュータが現在のマシンよりもはるかに限られたリソースを持っていた場合に非常に望ましいものでした(要因の使用の背景にある動機の詳細な履歴については、 stringsAsFactors :Unauthorized Biographyを参照してください)。メモリ使用の違いは、 Colorオブジェクトでも見ることができます。ご覧のように、 Colorを文字として保存するには、Factorオブジェクトの約1.7倍のメモリが必要です。

#* Amount of memory required to store Color as a factor.
object.size(Color)
4624 bytes
#* Amount of memory required to store Color as a character
object.size(as.character(Color))
8232 bytes

整数をレベルにマッピングする

ファクタの内部的な計算はオブジェクトを整数と見なしますが、人間が消費する表現は文字レベルです。例えば、

head(Color)
[1] Blue   Blue   Green  Yellow Red    Yellow  
Levels: Blue Green Red Yellow

人間の理解の方が簡単です

head(as.numeric(Color))
[1] 1 1 2 4 3 4

Rが文字表現を内部整数値にマッチさせる方法の概略図は次のとおりです。

head(levels(Color)[as.numeric(Color)])
[1] "Blue"   "Blue"   "Green"  "Yellow" "Red"    "Yellow"

これらの結果を

head(Color)
[1] Blue   Blue   Green  Yellow Red    Yellow  
Levels: Blue Green Red Yellow

近代的な要素の使用

2007年に、Rは、文字ベクトルのメモリ負担を軽減した文字のハッシング方法を紹介しました( stringsAsFactors :Unauthorized Biography )。文字が因子より1.7倍多くの記憶スペースを必要とすると判断した場合、それはRの最近のバージョンで計算されたことに注意してください。これは、文字ベクトルのメモリ使用が2007年より前に課税されたことを意味します。

近代的なRのハッシュ方法や現代のコンピュータのはるかに大きなメモリリソースのおかげで、文字の値を格納する際のメモリ効率の問題は非常に小さな問題になりました。 Rコミュニティにおける一般的な態度は、ほとんどの状況での因子に対する文字ベクトルの選択です。要素からのシフトの主な原因は次のとおりです。

  1. 非構造化および/または緩やかに制御された文字データの増加
  2. ユーザーがキャラクターではなく因子を扱っていることを忘れてしまったときに、ファクターが望みどおりに行動しない傾向

最初のケースでは、フリーテキストやオープンレスポンスフィールドを要素として保存するのは意味がありません。レベルごとに複数の観察を可能にするパターンは存在しない可能性があります。あるいは、データ構造が注意深く制御されていない場合、同じカテゴリ(例えば、「青」、「青」、および「青」)に対応する複数のレベルを得ることが可能である。そのような場合、多くの人は、因子に変換する前に、これらの矛盾を文字として管理することを好む(変換がまったく行われない場合)。

2番目のケースでは、ユーザーが文字ベクトルを扱っていると思っている場合、特定のメソッドが予期したとおりに応答しないことがあります。この基本的な理解は、スクリプトとコードをデバッグする際に混乱と不満を招くことがあります。厳密に言えば、これはユーザーの過ちとみなすことができますが、ほとんどのユーザーは要因を使用しないでこれらの状況を完全に回避することができます。

要素の基本的な作成

因数は、Rのカテゴリ変数を表す1つの方法です。因子は、内部的に整数のベクトルとして格納されます 。与えられた文字ベクトルの固有の要素は、要素のレベルとして知られています 。デフォルトでは、レベルがユーザーによって提供されない場合、Rはベクトル内の一意の値のセットを生成し、これらの値を英数字でソートし、それらをレベルとして使用します。

 charvar <- rep(c("n", "c"), each = 3)
 f <- factor(charvar)
 f
 levels(f)

> f
[1] n n n c c c
Levels: c n
> levels(f)
[1] "c" "n"

レベルの順序を変更する場合は、レベルを手動で指定するための1つのオプションがあります。

levels(factor(charvar, levels = c("n","c")))

> levels(factor(charvar, levels = c("n","c")))
[1] "n" "c"

因子には多くの性質があります。たとえば、レベルにラベルを付けることができます。

> f <- factor(charvar, levels=c("n", "c"), labels=c("Newt", "Capybara"))
> f
[1] Newt     Newt     Newt     Capybara Capybara Capybara
Levels: Newt Capybara

割り当てることができるもう1つのプロパティは、要素が順序付けられているかどうかです。

> Weekdays <- factor(c("Monday", "Wednesday", "Thursday", "Tuesday", "Friday", "Sunday", "Saturday"))
> Weekdays
[1] Monday    Wednesday Thursday  Tuesday   Friday    Sunday    Saturday 
Levels: Friday Monday Saturday Sunday Thursday Tuesday Wednesday
> Weekdays <- factor(Weekdays, levels=c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"), ordered=TRUE)
> Weekdays
[1] Monday    Wednesday Thursday  Tuesday   Friday    Sunday    Saturday 
Levels: Monday < Tuesday < Wednesday < Thursday < Friday < Saturday < Sunday

因子のレベルが使用されなくなったら、関数droplevels()を使用してdroplevels()削除することができます:

> Weekend <- subset(Weekdays, Weekdays == "Saturday" |  Weekdays == "Sunday")
> Weekend
[1] Sunday   Saturday
Levels: Monday < Tuesday < Wednesday < Thursday < Friday < Saturday < Sunday
> Weekend <- droplevels(Weekend)
> Weekend
[1] Sunday   Saturday
Levels: Saturday < Sunday

因子レベルをリストに統合する

おそらく、カテゴリの1つにおける疎なデータのために、因子レベルをより少ないグループに統合することが望ましい場合があります。カテゴリ名の綴りや大文字小文字が異なる場合にも発生する可能性があります。例として考慮する要因

set.seed(1)
colorful <- sample(c("red", "Red", "RED", "blue", "Blue", "BLUE", "green", "gren"),
                   size = 20,
                   replace = TRUE)
colorful <- factor(colorful)

Rは大文字と小文字を区別するため、このベクトルの頻度テーブルは次のようになります。

table(colorful)
colorful  
blue  Blue  BLUE green  gren   red   Red   RED  
   3     1     4     2     4     1     3     2

ただし、この表はデータの真の分布を表すものではなく、カテゴリは青、緑、赤の3つのタイプに効果的に縮小できます。 3つの例が提供されています。最初は明白な解決策のように見えますが、実際には解決策はありません。 2番目の方法は実用的な解決方法を示していますが、冗長で計算コストがかかります。 3番目は明らかな解決策ではありませんが、比較的コンパクトで計算効率が良いです。

factorfactor_approach )を使用したレベルの統合

factor(as.character(colorful),
       levels = c("blue", "Blue", "BLUE", "green", "gren", "red", "Red", "RED"),
       labels = c("Blue", "Blue", "Blue", "Green", "Green", "Red", "Red", "Red"))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Blue Blue Green Green Red Red Red
Warning message:
In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) else paste0(labels,  :
  duplicated levels in factors are deprecated

レベルが重複していることに注意してください。私たちはまだ "青"の3つのカテゴリーを持っていますが、それはレベルをまとめるという作業を完了しません。さらに、複製されたレベルは推奨されなくなりました。これは、このコードが将来エラーを生成する可能性があることを意味します。

ifelseifelse_approach )を使用してレベルを統合する

factor(ifelse(colorful %in% c("blue", "Blue", "BLUE"),
       "Blue",
       ifelse(colorful %in% c("green", "gren"),
              "Green",
              "Red")))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Green Red

このコードは目的の結果を生成しますが、ネストされたifelseステートメントを使用する必要があります。このアプローチには何も問題はありませんが、ネストされたifelseステートメントの管理は退屈な作業であり、慎重に行わなければなりません。

ファクターレベルをリストに統合する( list_approach

あまり明白でないレベルの統合方法は、各要素の名前が目的のカテゴリ名であるリストを使用することです。要素は、目的のカテゴリにマップする必要がある要素のレベルの文字ベクトルです。これには、新しいオブジェクトを割り当てることなく、ファクタのlevels属性に直接作業するという追加の利点があります。

levels(colorful) <- 
     list("Blue" = c("blue", "Blue", "BLUE"),
          "Green" = c("green", "gren"),
          "Red" = c("red", "Red", "RED"))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Green Red

各アプローチのベンチマーキング

これらのアプローチのそれぞれを実行するのに要する時間を以下に要約する。 (スペースのために、この要約を生成するコードは表示されません)

Unit: microseconds
          expr     min      lq      mean   median      uq     max neval cld
        factor  78.725  83.256  93.26023  87.5030  97.131 218.899   100  b 
        ifelse 104.494 107.609 123.53793 113.4145 128.281 254.580   100   c
 list_approach  49.557  52.955  60.50756  54.9370  65.132 138.193   100 a

リストアプローチはifelseアプローチの約2倍の速さで実行されます。ただし、非常に大量のデータがある場合を除いて、実行時間の差は、マイクロ秒またはミリ秒単位で測定される可能性があります。そのようなわずかな時間差で、効率はどのアプローチを使用するかの決定を導く必要はありません。代わりに、使い慣れた、快適なアプローチを使用して、あなたとあなたの共同作業者が今後のレビューで理解する方法を使用してください。

要因

要因は、1つのベクトルを考えるR.でカテゴリ変数を表現する方法であるx値を使用して文字に変換することができるas.character() 、デフォルト引数factor()as.factor()の各個別要素に整数を割り当てますベクトル、レベル属性、ラベル属性などがあります。レベルはxが取る可能性のある値であり、ラベルは指定された要素であるか、ユーザーによって決定されます。

ファクタがどのように機能するかを例として、デフォルト属性、カスタムレベル、カスタムレベル、およびラベルを含む要素を作成します。

# standard
factor(c(1,1,2,2,3,3))
[1] 1 1 2 2 3 3
Levels: 1 2 3

ファクタが取ることができる可能な値の数がベクトルの現在の値よりも大きいことをユーザが知っている場合、インスタンスが発生する可能性があります。このために、私たちはfactor()レベルを割り当てます。

factor(c(1,1,2,2,3,3),
         levels = c(1,2,3,4,5))
[1] 1 1 2 2 3 3
Levels: 1 2 3 4 5

スタイル目的のために、ユーザは各レベルにラベルを割り当てることができる。デフォルトでは、ラベルはレベルの文字表現です。ここでは、因子の可能なレベルのそれぞれにラベルを割り当てます。

factor(c(1,1,2,2,3,3),
       levels = c(1,2,3,4,5),
       labels = c("Fox","Dog","Cow","Brick","Dolphin"))
[1] Fox Fox Dog Dog Cow Cow
Levels: Fox Dog Cow Brick Dolphin

通常、因子は、 ==!=と因子が同じレベルである場合にのみ比較することができます。以下の要因の比較は、要因が異なる要因レベルを有するために等しく見えても失敗する。

factor(c(1,1,2,2,3,3),levels = c(1,2,3)) == factor(c(1,1,2,2,3,3),levels = c(1,2,3,4,5))
Error in Ops.factor(factor(c(1, 1, 2, 2, 3, 3), levels = c(1, 2, 3)),  : 
  level sets of factors are different

これは、RHSの余分なレベルは、Rが有意義な方法でそれらを比較するために各要因についての十分な情報を持っていないことを意味するので意味があります。

演算子<<=>および>=は、順序付けられた要素に対してのみ使用できます。これらは、依然として線形の順序を有するカテゴリ値を表すことができる。 orderedファクタは、 ordered = TRUE引数をfactor関数に指定するか、 ordered関数を使用するだけで作成できます。

x <- factor(1:3, labels = c('low', 'medium', 'high'), ordered = TRUE)
print(x)
[1] low    medium high  
Levels: low < medium < high

y <- ordered(3:1, labels = c('low', 'medium', 'high'))
print(y)
[1] high   medium low   
Levels: low < medium < high

x < y
[1]  TRUE FALSE FALSE

詳細については、 Factorのドキュメントを参照してください。

変更および並べ替えの要因

ファクタがデフォルトで作成されるとき、 levelsは入力に適用されるas.characterによってas.characterされ、アルファベット順に並べられます。

charvar <- rep(c("W", "n", "c"), times=c(17,20,14))
f <- factor(charvar)
levels(f)
# [1] "c" "n" "W"

状況によっては、 levelsのデフォルトの順序(アルファベット順/字句順)の扱いが受け入れられます。たとえば、周波数をplotするだけの場合は、次のようになります。

plot(f,col=1:length(levels(f)))

ここに画像の説明を入力

しかし、 levels異なる順序が必要な場合は、 levelsまたはlabelsパラメータでこれを指定する必要があります(ここでの「順序」の意味は順序付けられた要素とは異なります)。状況に応じてそのタスクを達成するための多くの選択肢があります。

1.因子を再定義する

可能であれば、 levelsパラメータを使用して、必要な順序で因子を再作成することができます。

ff <- factor(charvar, levels = c("n", "W", "c"))
levels(ff)
# [1] "n" "W" "c"
 
gg <- factor(charvar, levels = c("W", "c", "n"))
levels(gg)
# [1] "W" "c" "n"

入力レベルが所望の出力レベルと異なる場合、 levelsパラメータを許容可能な入力値の「フィルタ」にするlabelsパラメータを使用しますが、引数としてfactorベクトルの "levels"の最終値をそのまま残しますlabels

fm <- factor(as.numeric(f),levels = c(2,3,1),
             labels = c("nn", "WW", "cc"))
levels(fm)
# [1] "nn" "WW" "cc"

fm <- factor(LETTERS[1:6], levels = LETTERS[1:4],  # only 'A'-'D' as input
                 labels = letters[1:4])            # but assigned to 'a'-'d'
fm
#[1] a    b    c    d    <NA> <NA>
#Levels: a b c d

2. relevel関数を使用する

1つの具体的なlevelが最初にある必要がある場合、私たちはrelevelを使用することができます。これは、例えば、仮説を検証するためにbaseカテゴリが必要な場合の統計分析のコンテキストで発生します。

g<-relevel(f, "n") # moves n to be the first level
levels(g)
# [1] "n" "c" "W"  

検証できるように、 fgは同じです

all.equal(f, g)
# [1] "Attributes: < Component “levels”: 2 string mismatches >"
all.equal(f, g, check.attributes = F)
# [1] TRUE

3.並べ替えの要因

数値、部分的な結果、計算された統計、または前の計算に基づいてlevelsreorder必要がある場合があります。 levels 頻度に基づいて並べ替えましょう

table(g)
# g
#  n  c  W 
# 20 14 17 

reorder関数は一般的です( help(reorder)参照してください)が、この文脈では、次のものが必要です: x 、この場合はfactor; Xは、 xと同じ長さの数値です。 Xに適用され、 xレベルによって計算される関数で、 levels順位を決定する関数FUNは、デフォルトで増加します。その結果は、同じ要素であり、そのレベルは並べ替えられています。

g.ord <- reorder(g,rep(1,length(g)), FUN=sum) #increasing
levels(g.ord)
# [1] "c" "W" "n"

減少する順序を得るために、負の値( -1

g.ord.d <- reorder(g,rep(-1,length(g)), FUN=sum)
levels(g.ord.d)
# [1] "n" "W" "c"

再度、要因は他の要因と同じです。

data.frame(f,g,g.ord,g.ord.d)[seq(1,length(g),by=5),] #just same lines
#    f g g.ord g.ord.d
# 1  W W     W       W
# 6  W W     W       W
# 11 W W     W       W
# 16 W W     W       W
# 21 n n     n       n
# 26 n n     n       n
# 31 n n     n       n
# 36 n n     n       n
# 41 c c     c       c
# 46 c c     c       c
# 51 c c     c       c

因子変数に関連する量的変数がある場合、他の関数を使用してlevelsを並べ替えることができlevels 。詳細については、 irisデータ( help("iris")Sepal.WidthSpecies因子の平均値Sepal.Widthを使用して並べ替えます。

miris <- iris  #help("iris") # copy the data
with(miris, tapply(Sepal.Width,Species,mean))
#    setosa versicolor  virginica 
#     3.428      2.770      2.974 

miris$Species.o<-with(miris,reorder(Species,-Sepal.Width))
levels(miris$Species.o)
# [1] "setosa"     "virginica"  "versicolor"

通常のboxplot (発言: with(miris, boxplot(Petal.Width~Species) )の順になespeciesが表示されます:setosa、versicolor 、およびvirginicaのしかし、注文した係数を用いて、我々はその平均が注文の種を得る。 Sepal.Width

boxplot(Petal.Width~Species.o, data = miris,
        xlab = "Species", ylab = "Petal Width",
        main = "Iris Data, ordered by mean sepal width", varwidth = TRUE,
        col = 2:4) 

ここに画像の説明を入力

さらに、 levelsの名前を変更したり、グループにまとめたり、新しいlevels追加することもできlevels 。そのためには、同じ名前levels関数を使用しlevels

f1<-f
levels(f1)
# [1] "c" "n" "W"
levels(f1) <- c("upper","upper","CAP") #rename and grouping
levels(f1)
# [1] "upper" "CAP" 

f2<-f1
levels(f2) <- c("upper","CAP", "Number") #add Number level, which is empty
levels(f2)
# [1] "upper"  "CAP"    "Number"
f2[length(f2):(length(f2)+5)]<-"Number" # add cases for the new level
table(f2)
# f2
#  upper    CAP Number 
#     33     17      6 

f3<-f1
levels(f3) <- list(G1 = "upper", G2 = "CAP", G3 = "Number") # The same using list
levels(f3)
# [1] "G1" "G2" "G3"
f3[length(f3):(length(f3)+6)]<-"G3" ## add cases for the new level
table(f3)
# f3
# G1 G2 G3 
# 33 17  7 

- 順序付けられた要因

最後に、 ordered要素は要因とは異なり、最初のfactors順序データを表すのに使用され、2つ目は名目上のデータを使用することがわかります 。最初は、順序付けられた要素のlevelsの順序を変更するのは意味がありませんが、 labelsを変更することはできます。

ordvar<-rep(c("Low", "Medium", "High"), times=c(7,2,4))

of<-ordered(ordvar,levels=c("Low", "Medium", "High"))
levels(of)
# [1] "Low"    "Medium" "High" 

of1<-of
levels(of1)<- c("LOW", "MEDIUM", "HIGH")
levels(of1)
# [1] "LOW"    "MEDIUM" "HIGH"
is.ordered(of1)
# [1] TRUE
of1
# [1] LOW    LOW    LOW    LOW    LOW    LOW    LOW    MEDIUM MEDIUM HIGH   HIGH   HIGH   HIGH  
# Levels: LOW < MEDIUM < HIGH

ゼロからの要因の再構築

問題

因子は、Rのレベルと呼ばれる一連のカテゴリから値を取る変数を表現するために使用されます。たとえば、空、低、正常、完全の4つのレベルで、バッテリーのエネルギーレベルによって特徴付けられる実験もあります。次に、5つの異なるサンプリングサイトについて、これらのレベルを以下のように特定することができます。

フルフルノーマル

通常、データベースまたは他の情報源では、これらのデータの取り扱いは、カテゴリまたはレベルに関連付けられた任意の整数インデックスによって行われます。与えられた例では、1 =空、2 =低、3 =正常、4 =完全、次のように5つのサンプルをコード化すると仮定します。

4、4、3、1、2

あなたの情報源、例えばデータベースからは、エンコードされた整数のリストと、各整数を各level-keywordと関連付けるカタログだけが存在する可能性があります。その情報からどのようにRの要素を再構成することができますか?

溶液

サンプルを表す20個の整数のベクトルをシミュレートします。それぞれのサンプルは4つの異なる値の1つを持ちます。

set.seed(18)
ii <- sample(1:4, 20, replace=T)
ii

[1] 4 3 4 1 1 3 2 3 2 1 3 4 1 2 4 1 3 1 4 1

最初のステップは、レベルまたはカテゴリが正確に1から4までの数字である、前のシーケンスからの要因を作ることです。

fii <- factor(ii, levels=1:4) # it is necessary to indicate the numeric levels
fii

[1] 4 3 4 1 1 3 2 3 2 1 3 4 1 2 4 1 3 1 4 1
レベル:1 2 3 4

今度は、単にindexタグで作成した要素をドレスする必要があります。

levels(fii) <- c("empty", "low", "normal", "full")
fii

[1]完全ノーマル完全空空ノーマル低ノーマル低空
[11]通常完全空低完全空空通常空完全空
レベル:空の低い普通のフル



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow