/usr/lib/python2.7/dist-packages/rpy2/robjects/numpy2ri.py is in python-rpy2 2.4.4-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | import rpy2.robjects as ro
import rpy2.robjects.conversion as conversion
import rpy2.rinterface as rinterface
from rpy2.rinterface import SexpVector, ListSexpVector, \
LGLSXP, INTSXP, REALSXP, CPLXSXP, STRSXP, VECSXP, NULL
import numpy
#from rpy2.robjects.vectors import DataFrame, Vector, ListVector
# The possible kind codes are listed at
# http://numpy.scipy.org/array_interface.shtml
_kinds = {
# "t" -> not really supported by numpy
"b": rinterface.LGLSXP,
"i": rinterface.INTSXP,
# "u" -> special-cased below
"f": rinterface.REALSXP,
"c": rinterface.CPLXSXP,
# "O" -> special-cased below
"S": rinterface.STRSXP,
"U": rinterface.STRSXP,
# "V" -> special-cased below
#FIXME: datetime64 ?
#"datetime64":
}
#FIXME: the following would need further thinking & testing on
# 32bits architectures
_kinds['float64'] = rinterface.REALSXP
_vectortypes = (rinterface.LGLSXP,
rinterface.INTSXP,
rinterface.REALSXP,
rinterface.CPLXSXP,
rinterface.STRSXP)
def numpy2ri(o):
""" Augmented conversion function, converting numpy arrays into
rpy2.rinterface-level R structures. """
# allow array-likes to also function with this module.
if not isinstance(o, numpy.ndarray) and hasattr(o, '__array__'):
o = o.__array__()
if isinstance(o, numpy.ndarray):
if not o.dtype.isnative:
raise(ValueError("Cannot pass numpy arrays with non-native byte orders at the moment."))
# Most types map onto R arrays:
if o.dtype.kind in _kinds:
# "F" means "use column-major order"
vec = SexpVector(o.ravel("F"), _kinds[o.dtype.kind])
dim = SexpVector(o.shape, INTSXP)
#FIXME: no dimnames ?
#FIXME: optimize what is below needed/possible ? (other ways to create R arrays ?)
res = rinterface.baseenv['array'](vec, dim=dim)
# R does not support unsigned types:
elif o.dtype.kind == "u":
raise(ValueError("Cannot convert numpy array of unsigned values -- R does not have unsigned integers."))
# Array-of-PyObject is treated like a Python list:
elif o.dtype.kind == "O":
res = conversion.py2ri(list(o))
# Record arrays map onto R data frames:
elif o.dtype.kind == "V":
if o.dtype.names is None:
raise(ValueError("Nothing can be done for this numpy array type %s at the moment." % (o.dtype,)))
df_args = []
for field_name in o.dtype.names:
df_args.append((field_name,
conversion.py2ri(o[field_name])))
# XXX: Note that an .rcall() currently calls .default_ri2ro!
res = ro.baseenv["data.frame"].rcall(tuple(df_args), ro.globalenv)
# It should be impossible to get here:
else:
raise(ValueError("Unknown numpy array type."))
else:
res = ro.default_py2ri(o)
return res
def numpy2ro(o):
if isinstance(o, numpy.ndarray):
res = numpy2ri(o)
res = ro.vectors.rtypeof2rotype[res.typeof](res)
else:
res = ro.default_py2ro(o)
return res
def ri2numpy(o):
# XXX: data.frames are ending up as SexpVectors - not ListSexpVectors
# I changed this conditional, but the right fix may be to fix the class
# of these things?
if isinstance(o, SexpVector):
if 'data.frame' in o.rclass:
# R "factor" vectors will not convert well by default
# (will become integers), so we build a temporary list o2
# with the factors as strings.
o2 = list()
# An added complication is that the conversion defined
# in this module will make __getitem__ at the robjects
# level return numpy arrays
for column in rinterface.ListSexpVector(o):
if 'factor' in column.rclass:
levels = tuple(column.do_slot("levels"))
column = tuple(levels[x-1] for x in column)
o2.append(column)
names = o.do_slot('names')
if names is NULL:
res = numpy.rec.fromarrays(o2)
else:
res = numpy.rec.fromarrays(o2, names=tuple(names))
elif (o.typeof in _vectortypes) and (o.typeof != VECSXP):
res = numpy.asarray(o)
else:
# not a data.frame, yet is it still possible to convert it
res = ro.default_ri2ro(o)
else:
res = ro.default_ri2ro(o)
return res
def activate():
'''Set conversion paths back to numpy2ri versions
This will straightforwardly override an existing numpy2ri.activate()
'''
conversion.py2ri = numpy2ri
conversion.ri2ro = ri2numpy
conversion.py2ro = numpy2ro
def deactivate():
'''Set conversion paths back to robjects defaults
Note that this will also revert, e.g., pandas2ri.activate()
'''
conversion.py2ri = conversion.default_py2ri
conversion.ri2ro = conversion.default_ri2ro
conversion.py2ro = conversion.default_py2ro
|