def rbind(self, *args, **kwargs): """ bind objects as supplementary rows """ new_args = [conversion.ri2py(x) for x in args] new_kwargs = dict([(k, conversion.ri2py(v)) for k, v in kwargs.iteritems()]) res = self._rbind(self, *new_args, **new_kwargs) return conversion.ri2py(res)
def tabulate(self, nbins = None): """ Like the R function tabulate, count the number of times integer values are found """ if nbins is None: nbins = max(1, max(self)) res = self._tabulate(self) return conversion.ri2py(res)
def __dimnames_get(self): """ Return a list of name vectors (like the R function 'dimnames' does it).""" res = self._dimnames_get(self) res = conversion.ri2py(res) return res
def __init__(self, package_name, package_path=None): self.__package_name = package_name if package_path is None: package_path = packages.get_packagepath(package_name) self.__package_path = package_path #FIXME: handle the case of missing "aliases.rds" rpath = StrSexpVector((os.path.join(package_path, 'help', self.__aliases_info), )) rds = readRDS(rpath) rds = StrSexpVector(rds) class2methods = {} object2alias = {} for k, v in itertools.izip(rds.do_slot('names'), rds): if v.startswith("class."): classname = v[len("class."):] if classname in class2methods: methods = class2methods[classname] else: methods = [] methods.append(k.split(',')[0]) class2methods[classname] = methods else: object2alias[v] = k self.class2methods = class2methods self.object2alias = object2alias rpath = StrSexpVector((os.path.join(package_path, 'help', package_name + '.rdx'), )) self._rdx = conversion.ri2py(readRDS(rpath))
def __colnames_get(self): """ Column names :rtype: SexpVector """ res = self._colnames(self) return conversion.ri2py(res)
def from_csvfile(path, header = True, sep = ",", quote = "\"", dec = ".", row_names = rinterface.MissingArg, col_names = rinterface.MissingArg, fill = True, comment_char = "", as_is = False): """ Create an instance from data in a .csv file. """ path = conversion.py2ro(path) header = conversion.py2ro(header) sep = conversion.py2ro(sep) quote = conversion.py2ro(quote) dec = conversion.py2ro(dec) if row_names is not rinterface.MissingArg: row_names = conversion.py2ro(row_names) if col_names is not rinterface.MissingArg: col_names = conversion.py2ro(col_names) fill = conversion.py2ro(fill) comment_char = conversion.py2ro(comment_char) as_is = conversion.py2ro(as_is) res = DataFrame._read_csv(path, **{'header': header, 'sep': sep, 'quote': quote, 'dec': dec, 'row.names': row_names, 'col.names': col_names, 'fill': fill, 'comment.char': comment_char, 'as.is': as_is}) res = conversion.ri2py(res) return res
def __rownames_get(self): """ Row names :rtype: SexpVector """ res = self._rownames(self) return conversion.ri2py(res)
def formals(self): """ Return the signature of the underlying R function (as the R function 'formals()' would). """ res = self.__formals(self) res = conversion.ri2py(res) return res
def __init__(self, package_name, package_path = None): self.__package_name = package_name if package_path is None: package_path = packages.get_packagepath(package_name) self.__package_path = package_path #FIXME: handle the case of missing "aliases.rds" rpath = StrSexpVector((os.path.join(package_path, 'help', self.__aliases_info), )) rds = readRDS(rpath) rds = StrSexpVector(rds) class2methods = {} object2alias = {} for k, v in itertools.izip(rds.do_slot('names'), rds): if v.startswith("class."): classname = v[len("class."):] if classname in class2methods: methods = class2methods[classname] else: methods = [] methods.append(k.split(',')[0]) class2methods[classname] = methods else: object2alias[v] = k self.class2methods = class2methods self.object2alias = object2alias rpath = StrSexpVector((os.path.join(package_path, 'help', package_name + '.rdx'), )) self._rdx = conversion.ri2py(readRDS(rpath))
def __fill_rpy2r__(self): """ Fill the attribute _rpy2r """ name = self.__rname__ for rname in self._env: if rname in self._translation: rpyname = self._translation[rname] else: dot_i = rname.find('.') if dot_i > -1: rpyname = rname.replace('.', '_') if rpyname in self._rpy2r: msg = ('Conflict when converting R symbol'+\ ' to a Python symbol ' +\ '(%s -> %s while there is already'+\ ' %s)') %(rname, rpyname, rpyname) raise LibraryError(msg) else: rpyname = rname if rpyname in self.__dict__ or rpyname == '__dict__': raise LibraryError('The symbol ' + rname +\ ' in the package ' + name + \ ' is conflicting with ' +\ 'a Python object attribute') self._rpy2r[rpyname] = rname rpyobj = conversion.ri2py(self._env[rname]) if hasattr(rpyobj, '__rname__'): rpyobj.__rname__ = rname #FIXME: shouldn't the original R name be also in the __dict__ ? self.__dict__[rpyname] = rpyobj
def default_py2ro(o): """ Convert any Python object into an robject. :param o: object :rtype: :class:`rpy2.robjects.RObject (and subclasses)` """ res = conversion.py2ri(o) return conversion.ri2py(res)
def __dimnames_set(self, value): """ Return a list of name vectors (like the R function 'dimnames' does it).""" value = conversion.ri2py(value) res = self._dimnames_set(self, value) self.__sexp__ = res.__sexp__
def __call__(self, *args, **kwargs): new_args = [conversion.py2ri(a) for a in args] new_kwargs = {} for k, v in kwargs.iteritems(): new_kwargs[k] = conversion.py2ri(v) res = super(Function, self).__call__(*new_args, **new_kwargs) res = conversion.ri2py(res) return res
def __getitem__(self, i): # Make sure this is not a List returned # FIXME: should this be optimzed ? tmp = super(DataFrame, self).__getitem__(i) if tmp.typeof == rinterface.VECSXP: return DataFrame(tmp) else: return conversion.ri2py(tmp)
def default_py2ri(o): """ Convert arbitrary Python object to :class:`rpy2.rinterface.Sexp` to objects, creating an R object with the content of the Python object in the process (wich means data copying). :param o: object :rtype: :class:`rpy2.rinterface.Sexp` (and subclasses) """ if isinstance(o, RObject): res = rinterface.Sexp(o) if isinstance(o, Sexp): res = o elif isinstance(o, array.array): if o.typecode in ('h', 'H', 'i', 'I'): res = rinterface.SexpVector(o, rinterface.INTSXP) elif o.typecode in ('f', 'd'): res = rinterface.SexpVector(o, rinterface.REALSXP) else: raise (ValueError( "Nothing can be done for this array type at the moment.")) elif isinstance(o, bool): res = rinterface.SexpVector([ o, ], rinterface.LGLSXP) elif isinstance(o, int) or isinstance(o, long): # special case for NA_Logical if o is rinterface.NA_Logical: res = rinterface.SexpVector([ o, ], rinterface.LGLSXP) else: res = rinterface.SexpVector([ o, ], rinterface.INTSXP) elif isinstance(o, float): res = rinterface.SexpVector([ o, ], rinterface.REALSXP) elif isinstance(o, str): res = rinterface.SexpVector([ o, ], rinterface.STRSXP) elif isinstance(o, unicode): res = rinterface.SexpVector([ o, ], rinterface.STRSXP) elif isinstance(o, list): res = r.list(*[conversion.ri2py(conversion.py2ri(x)) for x in o]) elif isinstance(o, complex): res = rinterface.SexpVector([ o, ], rinterface.CPLXSXP) else: raise (ValueError( "Nothing can be done for the type %s at the moment." % (type(o)))) return res
def get(self, item, wantfun=False): """ Get a object from its R name/symol :param item: string (name/symbol) :rtype: object (as returned by :func:`conversion.ri2py`) """ res = super(Environment, self).get(item, wantfun=wantfun) res = conversion.ri2py(res) res.__rname__ = item return res
def factor(self): """ factor() -> FactorVector Construct a factor vector from a vector of strings. """ res = self._factorconstructor(self) return conversion.ri2py(res)
def svd(self, nu = None, nv = None, linpack = False): """ SVD decomposition. If nu is None, it is given the default value min(tuple(self.dim)). If nv is None, it is given the default value min(tuple(self.dim)). """ if nu is None: nu = min(tuple(self.dim)) if nv is None: nv = min(tuple(self.dim)) res = self._svd(self, nu = nu, nv = nv, LINPACK = False) return conversion.ri2py(res)
def svd(self, nu=None, nv=None, linpack=False): """ SVD decomposition. If nu is None, it is given the default value min(tuple(self.dim)). If nv is None, it is given the default value min(tuple(self.dim)). """ if nu is None: nu = min(tuple(self.dim)) if nv is None: nv = min(tuple(self.dim)) res = self._svd(self, nu=nu, nv=nv, LINPACK=False) return conversion.ri2py(res)
def sample(self, n, replace = False, probabilities = None): """ Draw a sample of size n from the vector. If 'replace' is True, the sampling is done with replacement. The optional argument 'probabilities' can indicate sampling probabilities. """ assert isinstance(n, int) assert isinstance(replace, bool) if probabilities is not None: probabilities = FloatVector(probabilities) res = self._sample(self, IntVector((n,)), replace = BoolVector((replace, )), prob = probabilities) res = conversion.ri2py(res) return res
def from_csvfile(path, header=True, sep=",", quote="\"", dec=".", row_names=rinterface.MissingArg, col_names=rinterface.MissingArg, fill=True, comment_char="", as_is=False): """ Create an instance from data in a .csv file. path : string with a path header : boolean (heading line with column names or not) sep : separator character quote : quote character row_names : column name, or column index for column names (warning: indexing starts at one in R) fill : boolean (fill the lines when less entries than columns) comment_char : comment character as_is : boolean (keep the columns of strings as such, or turn them into factors) """ path = conversion.py2ro(path) header = conversion.py2ro(header) sep = conversion.py2ro(sep) quote = conversion.py2ro(quote) dec = conversion.py2ro(dec) if row_names is not rinterface.MissingArg: row_names = conversion.py2ro(row_names) if col_names is not rinterface.MissingArg: col_names = conversion.py2ro(col_names) fill = conversion.py2ro(fill) comment_char = conversion.py2ro(comment_char) as_is = conversion.py2ro(as_is) res = DataFrame._read_csv( path, **{ 'header': header, 'sep': sep, 'quote': quote, 'dec': dec, 'row.names': row_names, 'col.names': col_names, 'fill': fill, 'comment.char': comment_char, 'as.is': as_is }) res = conversion.ri2py(res) return res
def __fill_rpy2r__(self, on_conflict='fail'): """ Fill the attribute _rpy2r. - on_conflict: 'fail' or 'warn' (default: 'fail') """ assert (on_conflict in ('fail', 'warn')) name = self.__rname__ for rname in self._env: if rname in self._translation: rpyname = self._translation[rname] else: dot_i = rname.find('.') if dot_i > -1: rpyname = rname.replace('.', '_') if rpyname in self._rpy2r: msg = ('Conflict when converting R symbol'+\ ' in the package "%s"' +\ ' to a Python symbol ' +\ '(%s -> %s while there is already'+\ ' %s)') %(self.__rname__, rname, rpyname, rpyname) if on_conflict == 'fail': raise LibraryError(msg) else: warn(msg) continue else: rpyname = rname if rpyname in self.__dict__ or rpyname == '__dict__': raise LibraryError('The symbol ' + rname +\ ' in the package "' + name + '"' +\ ' is conflicting with ' +\ 'a Python object attribute') self._rpy2r[rpyname] = rname if (rpyname != rname) and (rname in self._exported_names): self._exported_names.remove(rname) self._exported_names.add(rpyname) rpyobj = conversion.ri2py(self._env[rname]) if hasattr(rpyobj, '__rname__'): rpyobj.__rname__ = rname #FIXME: shouldn't the original R name be also in the __dict__ ? self.__dict__[rpyname] = rpyobj
def __fill_rpy2r__(self, on_conflict = 'fail'): """ Fill the attribute _rpy2r. - on_conflict: 'fail' or 'warn' (default: 'fail') """ assert(on_conflict in ('fail', 'warn')) name = self.__rname__ for rname in self._env: if rname in self._translation: rpyname = self._translation[rname] else: dot_i = rname.find('.') if dot_i > -1: rpyname = rname.replace('.', '_') if rpyname in self._rpy2r: msg = ('Conflict when converting R symbol'+\ ' in the package "%s"' +\ ' to a Python symbol ' +\ '(%s -> %s while there is already'+\ ' %s)') %(self.__rname__, rname, rpyname, rpyname) if on_conflict == 'fail': raise LibraryError(msg) else: warn(msg) continue else: rpyname = rname if rpyname in self.__dict__ or rpyname == '__dict__': raise LibraryError('The symbol ' + rname +\ ' in the package "' + name + '"' +\ ' is conflicting with ' +\ 'a Python object attribute') self._rpy2r[rpyname] = rname if (rpyname != rname) and (rname in self._exported_names): self._exported_names.remove(rname) self._exported_names.add(rpyname) rpyobj = conversion.ri2py(self._env[rname]) if hasattr(rpyobj, '__rname__'): rpyobj.__rname__ = rname #FIXME: shouldn't the original R name be also in the __dict__ ? self.__dict__[rpyname] = rpyobj
def set_accessors(cls, cls_name, where, acs): # set accessors (to be abandonned for the metaclass above ?) if where is None: where = rinterface.globalenv else: where = "package:" + str(where) where = StrSexpVector((where, )) for r_name, python_name, as_property, docstring in acs: if python_name is None: python_name = r_name r_meth = getmethod(StrSexpVector((r_name, )), signature=StrSexpVector((cls_name, )), where=where) r_meth = conversion.ri2py(r_meth) if as_property: setattr(cls, python_name, property(r_meth, None, None)) else: setattr(cls, python_name, lambda self: r_meth(self))
def set_accessors(cls, cls_name, where, acs): # set accessors (to be abandonned for the metaclass above ?) if where is None: where = rinterface.globalenv else: where = "package:" + str(where) where = rinterface.StrSexpVector((where, )) for r_name, python_name, as_property, docstring in acs: if python_name is None: python_name = r_name r_meth = getmethod(rinterface.StrSexpVector((r_name, )), signature = rinterface.StrSexpVector((cls_name, )), where = where) r_meth = conversion.ri2py(r_meth) if as_property: setattr(cls, python_name, property(r_meth, None, None)) else: setattr(cls, python_name, lambda self: r_meth(self))
def default_py2ri(o): """ Convert arbitrary Python object to :class:`rpy2.rinterface.Sexp` to objects, creating an R object with the content of the Python object in the process (wich means data copying). :param o: object :rtype: :class:`rpy2.rinterface.Sexp` (and subclasses) """ if isinstance(o, RObject): res = rinterface.Sexp(o) if isinstance(o, Sexp): res = o elif isinstance(o, array.array): if o.typecode in ('h', 'H', 'i', 'I'): res = rinterface.SexpVector(o, rinterface.INTSXP) elif o.typecode in ('f', 'd'): res = rinterface.SexpVector(o, rinterface.REALSXP) else: raise(ValueError("Nothing can be done for this array type at the moment.")) elif isinstance(o, bool): res = rinterface.SexpVector([o, ], rinterface.LGLSXP) elif isinstance(o, int) or isinstance(o, long): # special case for NA_Logical if o is rinterface.NA_Logical: res = rinterface.SexpVector([o, ], rinterface.LGLSXP) else: res = rinterface.SexpVector([o, ], rinterface.INTSXP) elif isinstance(o, float): res = rinterface.SexpVector([o, ], rinterface.REALSXP) elif isinstance(o, str): res = rinterface.SexpVector([o, ], rinterface.STRSXP) elif isinstance(o, unicode): res = rinterface.SexpVector([o, ], rinterface.STRSXP) elif isinstance(o, list): res = r.list(*[conversion.ri2py(conversion.py2ri(x)) for x in o]) elif isinstance(o, complex): res = rinterface.SexpVector([o, ], rinterface.CPLXSXP) else: raise(ValueError("Nothing can be done for the type %s at the moment." %(type(o)))) return res
def from_csvfile(path, header = True, sep = ",", quote = "\"", dec = ".", row_names = rinterface.MissingArg, col_names = rinterface.MissingArg, fill = True, comment_char = "", as_is = False): """ Create an instance from data in a .csv file. path : string with a path header : boolean (heading line with column names or not) sep : separator character quote : quote character row_names : column name, or column index for column names (warning: indexing starts at one in R) fill : boolean (fill the lines when less entries than columns) comment_char : comment character as_is : boolean (keep the columns of strings as such, or turn them into factors) """ path = conversion.py2ro(path) header = conversion.py2ro(header) sep = conversion.py2ro(sep) quote = conversion.py2ro(quote) dec = conversion.py2ro(dec) if row_names is not rinterface.MissingArg: row_names = conversion.py2ro(row_names) if col_names is not rinterface.MissingArg: col_names = conversion.py2ro(col_names) fill = conversion.py2ro(fill) comment_char = conversion.py2ro(comment_char) as_is = conversion.py2ro(as_is) res = DataFrame._read_csv(path, **{'header': header, 'sep': sep, 'quote': quote, 'dec': dec, 'row.names': row_names, 'col.names': col_names, 'fill': fill, 'comment.char': comment_char, 'as.is': as_is}) res = conversion.ri2py(res) return res
raise LibraryError("The R package %s could not be imported" %name) env = _as_env(rinterface.StrSexpVector(['package:'+name, ])) if signature_translation: pack = SignatureTranslatedPackage(env, name, translation = robject_translations) else: pack = Package(env, name, translation = robject_translations) return pack def wherefrom(symbol, startenv = rinterface.globalenv): """ For a given symbol, return the environment this symbol is first found in, starting from 'startenv' """ env = startenv obj = None tryagain = True while tryagain: try: obj = env[symbol] tryagain = False except LookupError, knf: env = env.enclos() if env.rsame(rinterface.emptyenv): tryagain = False else: tryagain = True return conversion.ri2py(env)
def _get_colnames(self): res = baseenv_ri["colnames"](self) return conversion.ri2py(res)
def eigen(self): """ Eigen values """ res = self._eigen(self) return conversion.ri2py(res)
def dot(self, m): """ Matrix multiplication """ res = self._dot(self, m) return conversion.ri2py(res)
def do_slot(self, name): return conversion.ri2py(super(RS4, self).do_slot(name))
def transpose(self): """ transpose the matrix """ res = self._transpose(self) return conversion.ri2py(res)
def getenvironment(self): """ Get the environment in which the formula is finding its symbols.""" res = self.do_slot(".Environment") res = conversion.ri2py(res) return res
def __getitem__(self, item): res = super(Environment, self).__getitem__(item) res = conversion.ri2py(res) res.__rname__ = item return res
def __getitem__(self, item): res = rinterface.globalenv.get(item) res = conversion.ri2py(res) res.__rname__ = item return res # FIXME: check that this is properly working def __cleanup__(self): rinterface.endEmbeddedR() del (self) def __str__(self): s = super(R, self).__str__() s += os.linesep version = self["version"] tmp = [n + ": " + val[0] for n, val in itertools.izip(version.names, version)] s += str.join(os.linesep, tmp) return s def __call__(self, string): p = self.parse(text=string) res = self.eval(p) return res r = R() globalenv = conversion.ri2py(rinterface.globalenv) baseenv = conversion.ri2py(rinterface.baseenv) emptyenv = conversion.ri2py(rinterface.emptyenv)
def rcall(self, *args): """ Wrapper around the parent method rpy2.rinterface.SexpClosure.rcall(). """ res = super(Function, self).rcall(*args) res = conversion.ri2py(res) return res
def rbind(self, *args, **kwargs): """ bind objects as supplementary rows """ new_args = [conversion.ri2py(x) for x in args] new_kwargs = dict([(k, conversion.ri2py(v)) for k,v in kwargs.iteritems()]) res = self._rbind(self, *new_args, **new_kwargs) return conversion.ri2py(res)
docstring in accessors: if where is None: where = rinterface.globalenv else: where = "package:" + str(where) where = StrSexpVector((where, )) if python_name is None: python_name = rname signature = StrSexpVector((cls_rname, )) r_meth = getmethod(StrSexpVector((rname, )), signature=signature, where=where) r_meth = conversion.ri2py(r_meth) if as_property: cls_dict[python_name] = property(r_meth, None, None, doc=docstring) else: cls_dict[python_name] = lambda self: r_meth(self) return type.__new__(mcs, name, bases, cls_dict) # playground to experiment with more metaclass-level automation class RS4Auto_Type(type):
def crossprod(self, m): """ crossproduct X'.Y""" res = self._crossprod(self, conversion.ri2py(m)) return conversion.ri2py(res)
def tcrossprod(self, m): """ crossproduct X.Y'""" res = self._tcrossprod(self, m) return conversion.ri2py(res)
def __getitem__(self, item): res = rinterface.globalenv.get(item) res = conversion.ri2py(res) res.__rname__ = item return res