import numpy
import rpy2
from rpy2 import robjects
import rpy2.robjects.numpy2ri
r = robjects.r
rpy2.robjects.numpy2ri.activate()
x = numpy.array( [1, 5, -99, 4, 5, 3, 7, -99, 6] )
mx = numpy.ma.masked_values( x, -99 )
print x # works, displays all values
print r.sd(x) # works, but uses -99 values in calculation
print mx # works, now -99 values are masked (--)
print r.sd(mx) # does not work - error
私は rpy2 と numpy の新しいユーザーです。RHEL5でR 2.14.1、python 2.7.1、rpy2 2.2.5、numpy 1.5.1を使用しています。
データを numpy 配列に読み込み、rpy2 関数を使用する必要があります。ただし、rpy2 で配列を使用する前に、欠損値をマスクする必要があります。
値のマスキングに問題はありませんが、結果のマスクされた配列で rpy2 を動作させることはできません。マスクされた numpy 配列では numpy2ri 変換が機能しないように見えますか? (以下のエラーを参照)
どうすればこれを機能させることができますか?マスクされた値を無視するように rpy2 に指示することは可能ですか? 後でより高度な統計を行うため、scipy/numpy を直接使用するのではなく、R に固執したいと思います。
ありがとう。
Traceback (most recent call last):
File "d.py", line 16, in <module>
print r.sd(mx) # does not work - error
File "/dev/py/lib/python2.7/site-packages/rpy2-2.2.5dev_20120227-py2.7-linux-x86_64.egg/rpy2/robjects/functions.py", line 82, in __call__
return super(SignatureTranslatedFunction, self).__call__(*args, **kwargs)
File "/dev/py/lib/python2.7/site-packages/rpy2-2.2.5dev_20120227-py2.7-linux-x86_64.egg/rpy2/robjects/functions.py", line 30, in __call__
new_args = [conversion.py2ri(a) for a in args]
File "/dev/py/lib/python2.7/site-packages/rpy2-2.2.5dev_20120227-py2.7-linux-x86_64.egg/rpy2/robjects/numpy2ri.py", line 36, in numpy2ri
vec = SexpVector(o.ravel("F"), _kinds[o.dtype.kind])
TypeError: ravel() takes exactly 1 argument (2 given)
更新: rpy2 はマスクされた numpy 配列を処理できないため、-99 値を numpy NaN 値に変換してみました。どうやら rpy2 は numpy NaN 値を R スタイルの NA 値として認識します。
以下のコードが機能するのは、r.sd() 呼び出しで、rpy2 に NA 値を使用しないように指示できるためです。しかし、最初の NaN 置換は、numpy マスクを適用するよりも明らかに遅くなります。
大規模なnumpy ndarray全体で-99からNaNへの置換を行うより高速な方法をPythonウィザードで教えてもらえますか? または、別のアプローチを提案しますか?
ありがとう。
# 'x' is a large numpy ndarray I am working with
# ('x' in the original code above was a small test array)
for i in range(900, 950): # random slice of numpy ndarray
for j in range(6225): # full extent across slice
if x[i][j] == -99:
x[i][j] = numpy.NaN
y = x[933] # random piece of converted range
sd = r.sd( y, **{'na.rm': 'TRUE'} ) # r.sd() call that ignores numpy NaN values
print sd