96

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

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

4

8 に答える 8

49

係数を使用する必要があります。はい、それらは苦痛である可能性がありますが、私の理論では、それらが苦痛である理由の90%は、read.tableデフォルトのread.csv引数であるためです(そしてほとんどのユーザーはこの微妙さを見逃しています)。stringsAsFactors = TRUElme4のようなモデル適合パッケージは、因子と順序付き因子を使用してモデルを微分適合させ、使用するコントラストのタイプを決定するため、これらは便利だと思います。また、グラフ作成パッケージもそれらを使用してグループ化します。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.framesを使用すると、の動作[.data.frame()が異なります。このメールまたはを参照してください?"[.data.frame"drop=TRUEon 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()幸いなことに、個々の因子またはaのすべての因子の未使用の因子レベルをドロップすることで因子を簡単にドロップできます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凡例に入らないようにする方法です。

内部的には、 sは属性レベルの文字ベクトル(およびfactorを参照)を持つ整数であり、クリーンです。レベル名を変更する必要がある場合(そして文字列を使用している場合)、これははるかに効率の悪い操作になります。そして、特に伝説のために、私はレベル名をたくさん変更します。文字ベクトルを使用して要素を偽造すると、1つの要素だけを変更して、誤って別の新しいレベルを作成するリスクがあります。attributes(iris$Species)class(attributes(iris$Species)$levels)ggplot

于 2010-08-10T01:52:26.127 に答える
31

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

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", ]
于 2010-08-10T07:37:27.060 に答える
20

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

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

factor文字列のセットに任意のソート順を与える方法を提供するなど、sの他の側面は、 sの有用な二次特性ですfactorが、それらが存在する理由ではありません。

于 2013-10-16T16:08:01.457 に答える
13

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

于 2010-08-10T02:38:26.453 に答える
6

なんて卑劣なタイトルでしょう。

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

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

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

于 2010-08-10T01:43:17.623 に答える
1

ファクターは、優れた「ユニークなケース」のバッジエンジンです。私はこれを何度もひどく再現しました、そして時々いくつかのしわにもかかわらず、それらは非常に強力です。

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説明されていません。

于 2016-09-06T15:03:19.050 に答える
0

ファクターでのみ、NAファクターレベルとして設定することでsを処理できます。多くの関数が値を省略しているため、これは便利NAです。おもちゃのデータを生成してみましょう。

df <- data.frame(x= rnorm(10), g= c(sample(1:2, 9, replace= TRUE), NA))

xグループ化の手段が必要な場合はg

aggregate(x ~ g, df, mean)
  g          x
1 1  1.0415156
2 2 -0.3071171

ご覧のとおり、がの場合の平均は得られませxん。代わりに使用する場合も同じ問題が当てはまります(を参照)。関数(デフォルトまたは一般的に)がsを考慮しない他の多くの同様の例があります。gNAbyby(df$x, list(df$g), mean)NA

NAただし、ファクターレベルとして追加できます。ここを参照してください:

aggregate(x ~ addNA(g), df, mean)
  addNA(g)          x
1        1 -0.2907772
2        2 -0.2647040
3     <NA>  1.1647002

xええ、どこgNAsがあるのか​​という意味がわかります。同じ出力が可能であると主張することができpaste0ます(try aggregate(x ~ paste0(g), df, mean))。しかし、 sを実際のaddNA欠落に逆変換できるのは私たちだけです。それでは、最初にで変換してから、逆変換してNAみましょう。gaddNA

df$g_addNA <- addNA(df$g)
df$g_back <- factor(as.character(df$g_addNA))
 [1] 2    2    1    1    1    2    2    1    1    <NA>
Levels: 1 2

これで、NAg_backは実際の欠落です。any(is.na(df$g_back))どちらがを返すかを確認しますTRUE

"NA"これは、元のベクトルに値があった奇妙な状況でも機能します。たとえば、ベクトルvec <- c("a", "NA", NA)はを使用して変換vec_addNA <- addNA(vec)でき、実際にはこれを次のように逆変換できます。

as.character(vec_addNA)
[1] "a"  "NA" NA

一方、私の知る限り、とは同じであるvec_paste0 <- paste0(vec)ため、逆変換することはできません。見るvec_paste0"NA"NA

vec_paste0
[1] "a"  "NA" "NA"

私は「ファクターでのみ、ファクターレベルとして設定することでNAを処理できる」という答えから始めました。実際、私は慎重に使用しますaddNAが、事実に関連するリスクに関係なく、addNAキャラクターに同様のオプションはありません。

于 2021-12-23T23:02:00.923 に答える
-2

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
于 2010-08-10T03:00:47.743 に答える