一所懸命に手抜きする

監査の仕事をしています。ITを利用し、良い意味で「手抜き」することは効率化と精度アップに役立つと思うんです。部下への引き継ぎのためにまずは諸々頭から引っ張り出そうとブログを始めました。

[ Main ]  [ 別館 ]
当ブログで取り上げられている事案やデータベース、人物等はすべてフィクションです。

factor型(2)_因子型(factor)から数値型(numeric)に戻すと数値が変わる?

数値(numeric型)を因子(factor型)として扱うと・・・

 前回、factor型(1)_Levels:・・・って?では
 Levels: ○,○・・・ のように記載されているのはfactor型で、文字型のデータをデータフレームに引き渡すとfactor型として処理されることをとりあげました。
 中身が数値であっても文字列として引き渡すとfactor型になってしまうのでした。

# Sample 1  vector→numeric
  nm<-c("2","3","4","5")
  as.numeric(nm)
##[1] 2 3 4 5

 Sample 1 では、文字(character型)ベクトルを数値(numeric型)に戻しています。"2"→2と当たり前に変換されています。

数値(numeric型)を因子(factor型)に変換すると数値が変わってしまうように見える

 次に、

# Sample 2  numeric→factor→numeric
  nm<-c(2,3,4,5)
  as.factor(nm)
##[1] 2 3 4 5
##Levels: 2 3 4 5
  as.numeric(as.factor(nm))
##[1] 1 2 3 4

 Sample 2 では、 数値(numeric型)ベクトルを因子(factor型)に変換した後、数値(numeric型)に戻しています。
 2→"2"→1 となっていて、数値が変わっています。この後の処理に支障をきたすことが多いでしょう。
 factorは元データをソートした結果を1から順に連番にして返しているようです。

文字(character)型の体裁の数値をdata.frameに変換した時も数値が変わってしまうように見える

 続いて二つのサンプルを比較してみます。

# Sample 3  numeric→data.frame(factor)→numeric
  nm<-c(2,3,4,5)
  df<-data.frame(nm)
  df$nm
##[1] 2 3 4 5
  as.numeric(df$nm) 
##[1] 2 3 4 5

 Sample 3 では数値ベクトルをデータフレームに変換していますが、そのまま数値として元の値で処理されています。

# Sample 4  (numeric)character→data.frame(factor)→numeric
  nm<-c("2","3","4","5")
  df<-data.frame(nm)
  df$nm
##[1] 2 3 4 5
##Levels: 2 3 4 5
  as.numeric(df$nm) 
##[1] 1 2 3 4

 Sample 4 では数値を文字型ベクトルとしてデータフレームに変換していますが、factor型として処理され、数値はもとの値とは変わっています。

ファイル読み込みのときにも注意

 データをファイルから読み込みデータフレームにする場合にも注意が必要です。
 数値の列のはずが、文字列として扱われてしまうとfactor型に変換されてしまいます。
 それはSample2,Sample4と同じことです。
 

factor型で数値が変わらないようにするための対策

対策1

 数値をfactor型に変換すると、as.numericで数値に戻してももとに戻らないことがあります(Sample5)。

# Sample 5
  nm<-c(2,3,4,5)
  as.factor(nm)
##[1] 2 3 4 5
##Levels: 2 3 4 5
  as.numeric(as.factor(nm))
##[1] 1 2 3 4

# Sample 6  counterplan
  as.character(as.factor(nm))
##[1] "2" "3" "4" "5"
  as.numeric(as.character(as.factor(nm)))
##[1] 2 3 4 5

 対策としては、Sample6のようにas.numeric(as.character())で一旦文字型に変換した後、数値型に戻すのが簡単かと思います。

対策2

 ファイルからの読み込みの際に勝手にfactor型に変換されて困るのであれば、read.csv() などで stringsAsFactors=FALSE を指定すれば問題が解消するでしょう。

read.table(...,stringsAsFactors=FALSE)
read.csv(...,stringsAsFactors=FALSE)
広告を非表示にする