web-dev-qa-db-ja.com

Rの要因:迷惑以上?

Rの基本的なデータ型の1つは因子です。私の経験では、要因は基本的に痛みであり、私はそれらを決して使用しません。私は常に文字に変換します。何かが足りないように感じます。

因子データ型が必要になるグループ化変数として因子を使用する関数の重要な例はありますか? shouldファクターを使用している特定の状況はありますか?

95
JD Long

要因を使用する必要があります。はい、彼らは痛みになる可能性がありますが、私の理論では、彼らが痛みである理由の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_ sでは、[.data.frame()の動作が異なります: このメールを参照 または_?"[.data.frame"_。 _drop=TRUE_ sで_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凡例を取得しないように選択したレベルを維持する方法です。

内部的には、factorsは属性レベルの文字ベクトルを持つ整数です(attributes(iris$Species)およびclass(attributes(iris$Species)$levels)を参照)。レベル名を変更する必要がある場合(および文字列を使用している場合)、これはmuch効率の低い操作になります。そして、特にggplot凡例の場合、レベル名を大幅に変更します。文字ベクトルでファクターを偽造すると、1つの要素だけを変更して、誤って別の新しいレベルを作成するリスクがあります。

49
Vince

順序付けられた要素は素晴らしいです。オレンジが好きでリンゴが嫌いなのに、ブドウを気にしないなら、奇妙なインデックスを管理する必要はありません。

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", ]
30
mdsumner

factorは、他の言語の列挙型に最も類似しています。その適切な使用法は、規定された値のセットの1つのみをとることができる変数です。これらの場合、許可されるすべての値が特定のデータセットに存在するわけではなく、「空の」レベルはそれを正確に反映します。

いくつかの例を考えてみましょう。米国全体で収集された一部のデータについては、州を要因として記録する必要があります。この場合、特定の州からケースが収集されなかったという事実が関連しています。その状態からのデータがあった可能性がありますが、(何らかの理由で、興味のある理由かもしれませんが)起こっていないことがありました。故郷が収集された場合、それは要因ではないでしょう。考えられる故郷の事前に定められたセットはありません。データが全国的にではなく3つの町から収集された場合、その町が要因となります。最初に3つの選択肢があり、これら3つの町の1つで関連する症例/データが見つからなかった場合、それは関連します。

一連の文字列に任意の並べ替え順序を与える方法を提供するなど、factorsのその他の側面は、factorsの有用な2次特性ですが、それらが存在する理由ではありません。

19
Brian Diggs

統計分析を行って実際にデータを調査しているとき、要因は素晴らしいです。ただし、その前に、データの読み取り、クリーニング、トラブルシューティング、マージ、および一般的な操作を行う場合、要因は完全に苦痛です。最近では、過去数年と同様に、多くの機能が改善され、要因をより適切に処理できるようになりました。たとえば、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の文字列関数は非常に使いやすく、論理的に使用できます。そのため、操作するときは、一般的に要素よりもキャラクターを好みます。

13
Farrel

なんてひどいタイトルでしょう!

多くの推定関数を使用すると、ダミー変数を簡単に定義するための要因を使用できると思います...しかし、私はそれを使用しません。

ユニークな観測値がほとんどない非常に大きな文字ベクトルがある場合に使用します。これにより、特に文字ベクトルの文字列が長い場合、メモリ消費を削減できます。

PS-私はタイトルについて冗談を言っています。あなたのツイートを見ました。 ;-)

6
Joshua Ulrich

ファクターは、優れた「固有のケース」バッジエンジンです。私はこれを何度もひどく作り直しましたが、ときどきいくつかのしわにもかかわらず、それらは非常に強力です。

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のこの機能については説明していません。

1
mdsumner