サーチ…
構文
- 因子(x = character()、レベル、ラベル=レベル、除外= NA、順序付け= is.ordered(x)、nmax = NA)
-
?factor
実行する?factor
オンラインでドキュメントを参照してください 。
備考
クラスfactor
持つオブジェクトは、特定の特性セットを持つベクトルです。
- 内部的に
integer
ベクトルとして格納されます。 - これは、値の文字表現を示す
levels
属性を保持します。 - そのクラスは
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コミュニティにおける一般的な態度は、ほとんどの状況での因子に対する文字ベクトルの選択です。要素からのシフトの主な原因は次のとおりです。
- 非構造化および/または緩やかに制御された文字データの増加
- ユーザーがキャラクターではなく因子を扱っていることを忘れてしまったときに、ファクターが望みどおりに行動しない傾向
最初のケースでは、フリーテキストやオープンレスポンスフィールドを要素として保存するのは意味がありません。レベルごとに複数の観察を可能にするパターンは存在しない可能性があります。あるいは、データ構造が注意深く制御されていない場合、同じカテゴリ(例えば、「青」、「青」、および「青」)に対応する複数のレベルを得ることが可能である。そのような場合、多くの人は、因子に変換する前に、これらの矛盾を文字として管理することを好む(変換がまったく行われない場合)。
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番目は明らかな解決策ではありませんが、比較的コンパクトで計算効率が良いです。
factor
( factor_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つのカテゴリーを持っていますが、それはレベルをまとめるという作業を完了しません。さらに、複製されたレベルは推奨されなくなりました。これは、このコードが将来エラーを生成する可能性があることを意味します。
ifelse
( ifelse_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"
検証できるように、 f
とg
は同じです
all.equal(f, g)
# [1] "Attributes: < Component “levels”: 2 string mismatches >"
all.equal(f, g, check.attributes = F)
# [1] TRUE
3.並べ替えの要因
数値、部分的な結果、計算された統計、または前の計算に基づいてlevels
をreorder
必要がある場合があります。 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.Width
、 Species
因子の平均値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]通常完全空低完全空空通常空完全空
レベル:空の低い普通のフル