Rの基本的なデータ型の1つは因子です。私の経験では、要素は基本的に苦痛であり、私はそれらを使用することはありません。私はいつもキャラクターに変換します。何かが足りないように感じます。
因子データ型が必要になるグループ化変数として因子を使用する関数のいくつかの重要な例はありますか?ファクターを使用する必要がある特定の状況はありますか?
Rの基本的なデータ型の1つは因子です。私の経験では、要素は基本的に苦痛であり、私はそれらを使用することはありません。私はいつもキャラクターに変換します。何かが足りないように感じます。
因子データ型が必要になるグループ化変数として因子を使用する関数のいくつかの重要な例はありますか?ファクターを使用する必要がある特定の状況はありますか?
回答:
係数を使用する必要があります。はい、彼らは苦痛になる可能性がありますが、私の理論では、彼らが苦痛である理由の90%は、デフォルトで、read.table
そしてread.csv
、そして引数が原因stringsAsFactors = TRUE
です(そして、ほとんどのユーザーはこの微妙さを逃しています)。lme4のようなモデルフィッティングパッケージは因子と順序付けされた因子を使用して、モデルを微分的に適合させ、使用するコントラストのタイプを決定するため、それらは有用であると私は言います。また、グラフ作成パッケージは、それらを使用してグループ化します。ggplot
ほとんどのモデルフィッティング関数は文字ベクトルを因子に強制変換するため、結果は同じです。ただし、コードに警告が表示されます。
lm(Petal.Length ~ -1 + Species, data=iris)
# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris)
# Coefficients:
# Speciessetosa Speciesversicolor Speciesvirginica
# 1.462 4.260 5.552
iris.alt <- iris
iris.alt$Species <- as.character(iris.alt$Species)
lm(Petal.Length ~ -1 + Species, data=iris.alt)
# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris.alt)
# Coefficients:
# Speciessetosa Speciesversicolor Speciesvirginica
# 1.462 4.260 5.552
警告メッセージ:で
model.matrix.default(mt, mf, contrasts)
:に
Species
変換された変数factor
トリッキーなことの1つは、全体drop=TRUE
です。ベクトルでは、これはデータに含まれていない要因のレベルを削除するのに適しています。例えば:
s <- iris$Species
s[s == 'setosa', drop=TRUE]
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa
s[s == 'setosa', drop=FALSE]
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica
ただし、を使用するとdata.frame
、の動作[.data.frame()
が異なります?"[.data.frame"
。このメールまたはを参照してください。s を使用drop=TRUE
しdata.frame
ても、想像どおりに機能しません。
x <- subset(iris, Species == 'setosa', drop=TRUE) # susbetting with [ behaves the same way
x$Species
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica
幸いにもdroplevels()
、個々の因子またはdata.frame
(R 2.12以降)のすべての因子の未使用の因子レベルを削除することで、因子を簡単に削除できます。
x <- subset(iris, Species == 'setosa')
levels(x$Species)
# [1] "setosa" "versicolor" "virginica"
x <- droplevels(x)
levels(x$Species)
# [1] "setosa"
これは、選択したレベルをggplot
凡例に入れないようにする方法です。
内部的には、factor
sは属性レベルの文字ベクトル(attributes(iris$Species)
およびを参照class(attributes(iris$Species)$levels)
)を持つ整数であり、クリーンです。レベル名を変更する必要がある場合(および文字列を使用している場合)、これははるかに効率の悪い操作になります。そして、特にggplot
伝説の場合、レベル名を頻繁に変更します。文字ベクトルを使用して因子を偽造した場合、1つの要素のみを変更し、誤って別の新しいレベルを作成するリスクがあります。
stringsAsFactors
関数ではありません。
順序付けられた要素は素晴らしいです。もし私がたまたまオレンジが好きで、リンゴが嫌いなら、ブドウを気にしないのであれば、奇妙なインデックスを管理する必要はありません。
d <- data.frame(x = rnorm(20), f = sample(c("apples", "oranges", "grapes"), 20, replace = TRUE, prob = c(0.5, 0.25, 0.25)))
d$f <- ordered(d$f, c("apples", "grapes", "oranges"))
d[d$f >= "grapes", ]
d$f <- ordered(d$f, c("apples", "grapes", "oranges"))
?私はそれがデータフレームでこれらを注文したと思ったでしょうが、その行を実行してデータフレームを印刷した後、何も変更されません。印刷された注文が変更されない場合でも、内部注文を課すだけですか?
A factor
は、他の言語の列挙型に最も類似しています。その適切な使用は、指定された値のセットの1つだけを受け取ることができる変数です。これらの場合、すべての可能な許容値が特定のデータセットに存在するわけではなく、「空」レベルはそれを正確に反映します。
いくつかの例を考えてみましょう。米国全体で収集された一部のデータについては、州を要因として記録する必要があります。この場合、特定の州からケースが収集されなかったという事実が関係します。その州からのデータがあった可能性がありますが、(何らかの理由で、関心の理由である可能性があります)ないことが起こりました。故郷が集まったとしても、それは要因にはなりません。考えられる出身地の事前設定されたセットはありません。全国ではなく3つの町からデータが収集された場合、その町は1つの要因になります。最初に3つの選択肢があり、これらの3つの町のいずれかで関連するケース/データが見つからなかった場合、それは関連しています。
factor
文字列のセットに任意のソート順を与える方法を提供するなど、sの他の側面は、sの有用な2次的な特性ですfactor
が、それらが存在する理由ではありません。
統計分析を行って実際にデータを調査しているとき、要因は素晴らしいです。ただし、その前に、データの読み取り、クリーニング、トラブルシューティング、マージ、および一般的な操作を行う場合、要因は非常に苦痛です。最近では、過去数年のように、多くの機能が改善され、要因をより適切に処理できるようになりました。たとえば、rbindはそれらとうまく連携します。サブセット関数の後に空のレベルを残しておくことは、それでもまったく迷惑だと思います。
#drop a whole bunch of unused levels from a whole bunch of columns that are factors using gdata
require(gdata)
drop.levels(dataframe)
因子のレベルを再コーディングしてラベルを変更するのは簡単であり、レベルを並べ替える素晴らしい方法もあることは知っています。私の脳はそれらを覚えることができず、使用するたびにそれを再学習する必要があります。再コーディングは、それよりもはるかに簡単です。
Rの文字列関数は非常に使いやすく論理的です。したがって、操作するときは、通常、ファクターよりもキャラクターを好みます。
droplevels()
。そして、それはデフォルトで因子を再配列しません。
なんて卑劣なタイトルだ!
多くの推定関数を使用すると、因子を使用して簡単にダミー変数を定義できると思いますが、私はそのためにそれらを使用しません。
ユニークな観測がほとんどない非常に大きな文字ベクトルがある場合に使用します。これにより、特に文字ベクトルの文字列が長めである場合に、メモリ消費を削減できます。
PS-私はタイトルについて冗談を言っています。ツイートを見ました。;-)
?factor
ば、R-2.6.0であり、それは言う、「文字列への各参照は、4または8バイトのポインタを必要とするのに対し、整数値は4バイトに格納されています。」文字列に8バイトが必要な場合、スペースを因数に変換して節約しませんか?
N=100000
I 391.8 KB対391.5 KBを得ました。したがって、factorはメモリをほとんど消費しません。
要因は、優れた「ユニークなケース」のバッジエンジンです。私はこれをひどく何度も再現しましたが、たまにいくつかのしわにもかかわらず、それらは非常に強力です。
library(dplyr)
d <- tibble(x = sample(letters[1:10], 20, replace = TRUE))
## normalize this table into an indexed value across two tables
id <- tibble(x_u = sort(unique(d$x))) %>% mutate(x_i = row_number())
di <- tibble(x_i = as.integer(factor(d$x)))
## reconstruct d$x when needed
d2 <- inner_join(di, id) %>% transmute(x = x_u)
identical(d, d2)
## [1] TRUE
このタスクを実行するより良い方法がある場合、それを確認したいのですが、この機能factor
については説明していません。
Tapply(および Aggregate)は、要因に依存しています。これらの関数の情報と努力の比率は非常に高いです。
たとえば、1行のコード(以下のtapplyの呼び出し)では、カットとカラーによってダイヤモンドの平均価格を取得できます。
> data(diamonds, package="ggplot2")
> head(dm)
Carat Cut Clarity Price Color
1 0.23 Ideal SI2 326 E
2 0.21 Premium SI1 326 E
3 0.23 Good VS1 327 E
> tx = with(diamonds, tapply(X=Price, INDEX=list(Cut=Cut, Color=Color), FUN=mean))
> a = sort(1:diamonds(tx)[2], decreasing=T) # reverse columns for readability
> tx[,a]
Color
Cut J I H G F E D
Fair 4976 4685 5136 4239 3827 3682 4291
Good 4574 5079 4276 4123 3496 3424 3405
Very Good 5104 5256 4535 3873 3779 3215 3470
Premium 6295 5946 5217 4501 4325 3539 3631
Ideal 4918 4452 3889 3721 3375 2598 2629