ぼやかないつもりのメモ(ブログ Ver)

つぶやきとメモの記録。更新はぼちぼち。

データの読み込み

データの読み込みがうまくいっているかどうかは、Rで解析を行う際に、結構「はまる」ポイントになる。経験的には、NAと空白の扱いで混乱が生じ、その後の解析にエラーが出て進まないというパターンが多いように思える。今日、同僚がはまっていたのも、まさにNAと空白の関係で、一緒にいろいろ調べた結果、read.csvを使ってデータを読み込むと、csvに含まれる空白のうち、数値データの列にある空白はNAとして扱われ、文字データの列にある空白は「空白」という分類として扱われることがわかった。さらに厄介なことに、この「空白」という分類は、扱いにくくNAのように除外するという行為が難しい。そのためスムーズな解析をするためには、read.csvする際に「na.strings = ""」しておいて、文字データの列の空白もNAとして扱われるようにしておくと良い。
(追記)read.tableやread.csvのヘルプを見ると、na.stringsの欄に、因子データでも空欄は欠損値として扱われると書いてある。下の実験からこれは間違いであると思うんだけど、どうしよう?このヘルプを見ると、数値と因子で挙動が異なるという点はかなり大きなバグかもしれない。
(追記の追記)mokjpnさんと@kohskeさんが指摘してくださったのだが、欠損値がNAになるのは、logical、integer、numeric、complexの時だった。やっぱり因子型では自分で処理しないといけないみたい。
(追記の追記の追記)mokjpnさんに指摘していただいた2つの方法を試したところ、1つ目のfactor関数をかけてlevelsを指定するという方法が自分の意図する動作となった。ぼくはデータ入力時に「欠損値は空白のまま」と決めているので、read.csvするときに「na.strings = ""」するやり方がもっとも適しているらしい。

a b c
on 8.903822147 M
off 6.107898784 M
8.662291241 M
off 8.136423437 F
on 6.615345318 F
off F
on 0.336759818 M
off 8.286749451
M
off 3.647321651 F
on 4.199119083 F
off 6.709562273 F
on 8.046072317 M
off 0.600200381 M

上のようなデータ(test.csv)を使って、以下に「na.strings = ""」を使った場合と、使わなかった場合を記録しておく。summaryの時点で違いは明らかで、テーブルにすると縦横の項目数が変わってくる。結果として、テーブルを確認せずにカイ2乗検定をしてしまうと、大きな間違いを招いてしまう。この辺は、かなり怖い点なので、解析の際には十分に確認をしてもらいたい。ちなみに使わずにできてしまった「空白」というカテゴリは、na.omitはもちろんsubset()を使っても取り除けなかった。

d1 <- read.csv("test.csv")
summary(d1)
(table1 <- xtabs(~ a + c, data = d1))
chisq.test(table1)
cor.test(as.numeric(d1$a), d1$b, method = "s")

d2 <- read.csv("test.csv", na.strings = "")
summary(d2)
(table2 <- xtabs(~ a + c, data = d2))
chisq.test(table2)
cor.test(as.numeric(d2$a), d2$b, method = "s")
> summary(d1)
   a           b          c    
    :2   Min.   :0.3368    :1  
 off:7   1st Qu.:4.0612   F:6  
 on :5   Median :6.6625   M:7  
         Mean   :5.8543        
         3rd Qu.:8.1740        
         Max.   :8.9038        
         NA's   :2             

> (table1 <- xtabs(~ a + c, data = d1))
     c
a       F M
      0 0 2
  off 1 4 2
  on  0 2 3

> chisq.test(table1)

        Pearson's Chi-squared test

data:  table1 
X-squared = 3.9429, df = 4, p-value = 0.4138

 警告メッセージ: 
In chisq.test(table1) :  カイ自乗近似は不正確かもしれません 

> cor.test(as.numeric(d1$a), d1$b, method = "s")

        Spearman's rank correlation rho

data:  as.numeric(d1$a) and d1$b 
S = 339.4095, p-value = 0.5611
alternative hypothesis: true rho is not equal to 0 
sample estimates:
       rho 
-0.1867464 

 警告メッセージ: 
In cor.test.default(as.numeric(d1$a), d1$b, method = "s") :
   タイのため正確な p 値を計算することができません 
> summary(d2)
    a           b             c    
 off :7   Min.   :0.3368   F   :6  
 on  :5   1st Qu.:4.0612   M   :7  
 NA's:2   Median :6.6625   NA's:1  
          Mean   :5.8543           
          3rd Qu.:8.1740           
          Max.   :8.9038           
          NA's   :2                

> (table2 <- xtabs(~ a + c, data = d2))
     c
a     F M
  off 4 2
  on  2 3

> chisq.test(table2)

        Pearson's Chi-squared test with Yates' continuity correction

data:  table2 
X-squared = 0.0764, df = 1, p-value = 0.7823

 警告メッセージ: 
In chisq.test(table2) :  カイ自乗近似は不正確かもしれません 

> cor.test(as.numeric(d2$a), d2$b, method = "s")

        Spearman's rank correlation rho

data:  as.numeric(d2$a) and d2$b 
S = 220, p-value = 1
alternative hypothesis: true rho is not equal to 0 
sample estimates:
rho 
  0 

 警告メッセージ: 
In cor.test.default(as.numeric(d2$a), d2$b, method = "s") :
   タイのため正確な p 値を計算することができません