LoginSignup
3
4

More than 3 years have passed since last update.

【R】data.frameで文字列型をfactor型にさせない

Last updated at Posted at 2019-06-20

as.data.frame()でもstringsAsFactorsの引数が使えること今更ながら知りまして、これを機にちょっとまとめてみました。

場面別にまとめました

データフレーム生成時

「引数にstringsAsFactors = Fを指定する」で解決します。

ファイルから読み込み時

下記データをただ読み込みと、3列目がfactor化してしまいます。

yes no churn
0.13717622958469677 0.8628237704153032 no
0.053731282512169964 0.94626871748783 no
0.12273577469177754 0.8772642253082225 no
0.1780542822350093 0.8219457177649907 yes
0.028350089708717996 0.971649910291282 no
> data.factor <- read.delim("pred.txt", header = T, sep = "\t", quote = "")
> str(data.factor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn: Factor w/ 2 levels "no","yes": 1 1 1 2 1 1 1 1 2 1 ...

引数にstringsAsFactors = Fを指定して、因子型化を防ぎます。

> data.nofactor <- read.delim("pred.txt", header = T, sep = "\t", quote = "", stringsAsFactors = F)
> str(data.nofactor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn : chr  "no" "no" "no" "yes" ...

ちなみに、readr::read_delim()等なら、読み込み時の型を指定できます。
ただ、データフレームではなくtibbleになります。

> tibble.data <- readr::read_delim("pred.txt", delim = "\t", quote = "", col_names = T, col_types = "nnc")
> str(tibble.data)
# Classes ‘spec_tbl_df’, ‘tbl_df’, ‘tbl’ and 'data.frame':  3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn : chr  "no" "no" "no" "yes" ...
#  - attr(*, "spec")=
#   .. cols(
#   ..   yes = col_number(),
#   ..   no = col_number(),
#   ..   churn = col_character(),
#   .. )

別のベクトルから生成するとき

同様に、引数にstringsAsFactors = Fを指定して、因子型化を防ぎます。

> data.factor <- data.frame(a = c(1,2,3), b = c(0.1,0.2,0.3), c = c("one","two","three"))
> str(data.factor)
# 'data.frame': 3 obs. of  3 variables:
#  $ a: num  1 2 3
#  $ b: num  0.1 0.2 0.3
#  $ c: Factor w/ 3 levels "one","three",..: 1 3 2
> data.nofactor <- data.frame(a = c(1,2,3), b = c(0.1,0.2,0.3), c = c("one","two","three"), stringsAsFactors = F)
> str(data.nofactor)
# 'data.frame': 3 obs. of  3 variables:
#  $ a: num  1 2 3
#  $ b: num  0.1 0.2 0.3
#  $ c: chr  "one" "two" "three"

as.data.frame()

as.data.frame()でデータフレームに変換するときでも、stringsAsFactors = Fです。
apply系でmatrixを出力した後にまたデータフレームに戻すときなどで使えるかと思います。

> data.matrix <- matrix(c("1","2","3","0.1","0.2","0.3","one","two","three"), 3, 3)
> data.matrix
#      [,1] [,2]  [,3]   
# [1,] "1"  "0.1" "one"  
# [2,] "2"  "0.2" "two"  
# [3,] "3"  "0.3" "three"
> data.factor <- as.data.frame(data.matrix)
> str(data.factor)
# 'data.frame': 3 obs. of  3 variables:
#  $ V1: Factor w/ 3 levels "1","2","3": 1 2 3
#  $ V2: Factor w/ 3 levels "0.1","0.2","0.3": 1 2 3
#  $ V3: Factor w/ 3 levels "one","three",..: 1 3 2
> data.nofactor <- as.data.frame(data.matrix, stringsAsFactors = F)
> str(data.nofactor)
# 'data.frame': 3 obs. of  3 variables:
#  $ V1: chr  "1" "2" "3"
#  $ V2: chr  "0.1" "0.2" "0.3"
#  $ V3: chr  "one" "two" "three"

カラムごとに変換

データフレーム生成後でも、factor型→charactor型に変換可能です。

as.character()

> str(data.factor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn: Factor w/ 2 levels "no","yes": 1 1 1 2 1 1 1 1 2 1 ...
> data.nofactor <- data.factor
> data.nofactor$churn <- as.character(data.nofactor$churn)
> str(data.nofactor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn : chr  "no" "no" "no" "yes" ...

levels()

"no"と"yes"の二つの因子としてラベル付けされているので、そのラベル名を返す処理を使えば、文字列型に変換できます。

> str(data.factor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn: Factor w/ 2 levels "no","yes": 1 1 1 2 1 1 1 1 2 1 ...
> levels(data.factor$churn)  # levels()の挙動確認
# [1] "no"  "yes"
> head(levels(data.factor$churn)[data.factor$churn], 5)  # levels()の挙動確認
# [1] "no" "no" "no" "yes" "no"
> data.nofactor <- data.factor
> data.nofactor$churn <- levels(data.nofactor$churn)[data.nofactor$churn]
> str(data.nofactor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn : chr  "no" "no" "no" "yes" ...

transform()

引数を増やしていけば、複数カラムの文字列型への変換が一行で書けます。
カラム名だけで書けるのでややすっきりします。

> str(data.factor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn: Factor w/ 2 levels "no","yes": 1 1 1 2 1 1 1 1 2 1 ...
> data.nofactor <- transform(data.factor, churn = levels(churn)[churn])
> str(data.nofactor)
# 'data.frame': 3326 obs. of  3 variables:
#  $ yes  : num  0.1372 0.0537 0.1227 0.1781 0.0284 ...
#  $ no   : num  0.863 0.946 0.877 0.822 0.972 ...
#  $ churn : chr  "no" "no" "no" "yes" ...

おわり

(こんなこと書くと元も子もないですが)as.data.frame()で非因子化の引数が使えることを知ったのは、公式のドキュメンテーションでした。
公式を参照するのは大事だなと思いつつ、小さなソリューションが見つかりやすくなればと思い、この記事を書いた次第です。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4