2012-03-14 5 views
4

最近、applyでこの奇妙な問題が発生しています。次の例を考えてみましょう:apply()はすべての列にNA値を指定しています

set.seed(42) 
df <- data.frame(cars, foo = sample(LETTERS[1:5], size = nrow(cars), replace = TRUE)) 
head(df) 
    speed dist foo 
1  4 2 E 
2  4 10 E 
3  7 4 B 
4  7 22 E 
5  8 16 D 
6  9 10 C 

私はそのdata.frameの各列に機能fun(たとえば、mean)を適用するapplyを使用したいです。 data.frameだけnumeric値を含むされている場合は、私は何の問題もありません:

apply(cars, 2, mean) 
speed dist 
15.40 42.98 

をしかし、私のdata.framenumericcharacterデータを含むとしようとしたとき、失敗するように見える:もちろん

apply(df, 2, mean) 
speed dist foo 
    NA NA NA 
Warning messages: 
1: In mean.default(newX[, i], ...) : 
    argument is not numeric or logical: returning NA 
2: In mean.default(newX[, i], ..) : 
    argument is not numeric or logical: returning NA     
3: In mean.default(newX[, i], ...) :        
    argument is not numeric or logical: returning NA 

、私はcharacter列のためにNAを得ることを期待していましたが、とにかくnumeric列の値を取得したいと思います。

sapply(df, class) 
    speed  dist  foo 
"numeric" "numeric" "factor" 

私はここで非常に明白な何かが欠けているように感じているので、どんな指針にも感謝します!

> sessionInfo() 
R version 2.14.1 (2011-12-22) 
Platform: x86_64-unknown-linux-gnu (64-bit) 

locale: 
[1] LC_CTYPE=en_GB.UTF-8  LC_NUMERIC=C    
[3] LC_TIME=en_GB.UTF-8  LC_COLLATE=en_GB.UTF-8  
[5] LC_MONETARY=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 
[7] LC_PAPER=C     LC_NAME=C     
[9] LC_ADDRESS=C    LC_TELEPHONE=C    
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base 

答えて

10

?applyの説明の最初の文は言う:

Xは、配列が、(例えば、データフレームのような)非ヌルDIM 値を持つクラスのオブジェクトではない場合それが二次元(例えば、データフレーム)であればas.matrixを介して配列 に強制しようとするか、 as.arrayを介して強制しようとします。

マトリックスはRで1つのタイプにしかなりません。データフレームがマトリックスに強制されると、文字列が1つでもあれば、すべてが文字として終了します。

私はあなたに代替の説明がありますので、ここに行きます。データフレームは本当に単なるリストなので、各列に関数を適用する場合は、代わりにlapplyまたはsapplyを使用します。

3

applyはマトリックス上で動作し、マトリックスはすべて1つのタイプでなければなりません。したがって、dfは行列に変換され、文字が含まれているため、すべての列が文字になります。

> apply(df, 2, class) 
     speed  dist   foo 
"character" "character" "character" 

、あなたが望む結果を得るplyrcolwisenumcolwise機能をチェックアウトします。

> numcolwise(mean)(df) 
    speed dist 
1 15.4 42.98 
2

data.frameの列に機能を適用しています。データから。フレームがリストされ、あなたが代わりにapplylapplyまたはsapplyを使用することができます。

sapply(df, mean) 

speed dist foo 
15.40 42.98 NA 
Warning message: 
In mean.default(X[[3L]], ...) : 
    argument is not numeric or logical: returning NA 

をそして、あなたは平均値を計算する前に、クラスの数値をテストする匿名関数を使用して、警告メッセージを削除することができます。

sapply(df, function(x)ifelse(is.numeric(x), mean(x), NA)) 

speed dist foo 
15.40 42.98 NA 
+0

を'suppressWarnings(sapply(df、mean))'を使って警告を削除することもできます。しかし、これは警告を抑止しますが、あなたのバージョンでは警告が表示されるのを抑止し、気にしないので、おそらくあなたの方が良い解決策になります。 – Dason