Подтвердить что ты не робот

Как использовать pandas dataframes и numpy массивы в Rpy2?

Я хотел бы использовать pandas для всех моих анализов вместе с numpy, но использовать Rpy2 для построения моих данных. Я хочу сделать все анализы с помощью pandas dataframes, а затем использовать полный график R через rpy2 для их построения. py2, и я использую ipython для построения. Каков правильный способ сделать это?

Почти все команды, которые я пытаюсь выполнить, не работают. Например:

  • Я пытаюсь построить разброс между двумя столбцами pandas DataFrame df. Я бы хотел, чтобы метки df использовались по оси x/y, так же, как и если бы они были фреймворком данных R. Есть ли способ сделать это? Когда я пытаюсь сделать это с помощью r.plot, я получаю этот таинственный сюжет:

In: r.plot(df.a, df.b) # df is pandas DataFrame

дает:

Out: rpy2.rinterface.NULL

что приводит к графику:

enter image description here

Как вы можете видеть, метки меток перепутаны и не читают метки осей из DataFrame, как это должно (ось X равна столбцу a df, а ось Y - столбец b).

  • Если я попытаюсь сделать гистограмму с помощью r.hist, она вообще не работает, что приведет к ошибке:

    In: r.hist(df.a)
    Out: 
    ...
    vectors.pyc in <genexpr>((x,))
        293         if l < 7:
        294             s = '[' + \
    --> 295                 ', '.join((p_str(x, max_width = math.floor(52 / l)) for x in self[ : 8])) +\
        296                 ']'
        297         else:
    
    vectors.pyc in p_str(x, max_width)
        287                     res = x
        288                 else:
    --> 289                     res = "%s..." % (str(x[ : (max_width - 3)]))
        290             return res
        291 
    
    TypeError: slice indices must be integers or None or have an __index__ method
    

И в результате этот сюжет:

enter image description here

Любая идея, что означает ошибка? И снова здесь, оси все испорчены и замусорены с тарабарщиками.

EDIT. Эта ошибка возникает только при использовании ipython. Когда я запускаю команду из script, она все же создает проблемный график, но, по крайней мере, работает без ошибок. Это должно быть что-то неправильно с вызовом этих команд из ipython.

  • Я также попытался преобразовать pandas DataFrame df в R DataFrame, как рекомендовано на плакате ниже, но это тоже не с этой ошибкой:

    com.convert_to_r_dataframe(mydf) # mydf is a pandas DataFrame
    ----> 1 com.convert_to_r_dataframe(mydf)
    in convert_to_r_dataframe(df, strings_as_factors)
        275     # FIXME: This doesn't handle MultiIndex
        276 
    --> 277     for column in df:
        278         value = df[column]
        279         value_type = value.dtype.type
    
    TypeError: iteration over non-sequence
    

Как я могу заставить эти базовые функции построения работать в pandas DataFrame (с метками графиков, считанных с ярлыков pandas DataFrame), а также получить преобразование между pandas DF в R DF работать?

EDIT2. Вот полный пример csv файла "test.txt" (http://pastebin.ca/2311928) и мой код, чтобы ответить на комментарий @dale:

import rpy2
from rpy2.robjects import r
import rpy2.robjects.numpy2ri
import pandas.rpy.common as com
from rpy2.robjects.packages import importr
from rpy2.robjects.lib import grid
from rpy2.robjects.lib import ggplot2
rpy2.robjects.numpy2ri.activate()
from numpy import *
import scipy

# load up pandas df
import pandas
data = pandas.read_table("./test.txt")
# plotting a column fails
print "data.c2: ", data.c2
r.plot(data.c2)
# Conversion and then plotting also fails
r_df = com.convert_to_r_dataframe(data)
r.plot(r_df)

Вызов для построения столбца "data.c2" завершается с ошибкой, хотя data.c2 является столбцом pandas df, и поэтому для всех целей и задач должен быть массив numpy. Я использую вызов activate(), поэтому я думал, что он будет обрабатывать этот столбец как массив numpy и начертить его.

Второй вызов для построения фрейма данных data после преобразования в R-фрейм также не выполняется. Почему это? Если я загружаю test.txt из R в качестве фрейма данных, я могу plot() его, и, поскольку мой фреймворк был преобразован из pandas в R, похоже, что он тоже должен работать.

Когда я пытаюсь использовать rmagic в ipython, он почему-то не запускает окно графика, хотя это не ошибка. То есть если я это сделаю:

In [12]: X = np.array([0,1,2,3,4])

In [13]: Y = np.array([3,5,4,6,7])
In [14]: import rpy2

In [15]: from rpy2.robjects import r

In [16]: import rpy2.robjects.numpy2ri

In [17]: import pandas.rpy.common as com

In [18]: from rpy2.robjects.packages import importr

In [19]: from rpy2.robjects.lib import grid

In [20]: from rpy2.robjects.lib import ggplot2


In [21]: rpy2.robjects.numpy2ri.activate()

In [22]: from numpy import *

In [23]: import scipy

In [24]: r.assign("x", X)
Out[24]: 
<Array - Python:0x592ad88 / R:0x6110850>
[       0,        1,        2,        3,        4]

In [25]: r.assign("y", Y)
<Array - Python:0x592f5f0 / R:0x61109b8>
[       3,        5,        4,        6,        7]

In [27]: %R plot(x,y)

Нет ошибки, но нет окна графика. В любом случае, я хотел бы придерживаться rpy2 и не полагаться на rmagic, если это возможно.

Спасибо.

4b9b3361

Ответ 1

[примечание: здесь работает ваш код в "edit 2" (Python 2.7, rpy2-2.3.2, R-1.15.2).]

Поскольку @dale упоминает его, когда объекты R являются анонимными (для объекта не существует символа R), R deparse(substitute()) в конечном итоге возвращает structure() объекта R, а возможное исправление - указать параметры "xlab" и "ylab"; для некоторых сюжетов вам также нужно будет указать main (заголовок).

Другим способом решения этой проблемы является использование R-формул и подача кадра данных (ниже, после того, как мы разработаем часть преобразования).

Забудьте о том, что находится в pandas.rpy. Он сломан и, кажется, игнорирует функции, доступные в rpy2.

Раннее быстрое исправление конверсии с ipython можно легко превратить в правильное преобразование. Я рассматриваю возможность добавления его в rpy2 codebase (с большим количеством колоколов и свистков), но в то же время просто добавьте следующий фрагмент после всех ваших импортных примеров. Он будет прозрачно преобразовывать объекты pandas 'DataFrame в rpy2 DataFrame всякий раз, когда выполняется R-вызов.

from collections import OrderedDict
py2ri_orig = rpy2.robjects.conversion.py2ri
def conversion_pydataframe(obj):
    if isinstance(obj, pandas.core.frame.DataFrame):
        od = OrderedDict()
        for name, values in obj.iteritems():
            if values.dtype.kind == 'O':
                od[name] = rpy2.robjects.vectors.StrVector(values)
            else:
                od[name] = rpy2.robjects.conversion.py2ri(values)
        return rpy2.robjects.vectors.DataFrame(od)
    elif isinstance(obj, pandas.core.series.Series):
        # converted as a numpy array
        res = py2ri_orig(obj) 
        # "index" is equivalent to "names" in R
        if obj.ndim == 1:
            res.names = ListVector({'x': ro.conversion.py2ri(obj.index)})
        else:
            res.dimnames = ListVector(ro.conversion.py2ri(obj.index))
        return res
    else:
        return py2ri_orig(obj) 
rpy2.robjects.conversion.py2ri = conversion_pydataframe

Теперь следующий код будет "просто работать":

r.plot(rpy2.robjects.Formula('c3~c2'), data)
# `data` was converted to an rpy2 data.frame on the fly
# and the a scatter plot c3 vs c2 (with "c2" and "c3" the labels on
# the "x" axis and "y" axis).

Я также отмечаю, что вы импортируете ggplot2, не используя его. В настоящее время преобразование должны быть явно запрошены. Например:

p = ggplot2.ggplot(rpy2.robjects.conversion.py2ri(data)) +\
    ggplot2.geom_histogram(ggplot2.aes_string(x = 'c3'))
p.plot()

Ответ 2

Вам нужно передать ярлыки явно при вызове функции r.plot.

r.plot([1,2,3],[1,2,3], xlab="X", ylab="Y")

Когда вы рисуете в R, он захватывает метки через deparse(substitute(x)), который по существу захватывает имя переменной из plot(testX, testY). Когда вы передаете объекты python через rpy2, это анонимный объект R и сродни следующему в R:

> deparse(substitute(c(1,2,3)))
[1] "c(1, 2, 3)"

поэтому вы получаете сумасшедшие ярлыки.

Много раз было проще использовать rpy2 для только для перемещения данных вперед и назад.

r.assign('testX', df.A)
r.assign('testY', df.B)
%R plot(testX, testY)

rdf = com.convert_to_r_dataframe(df)
r.assign('bob', rdf)
%R plot(bob$$A, bob$$B)

http://nbviewer.ipython.org/4734581/

Ответ 3

используйте rpy. преобразование является частью pandas, поэтому вам не нужно это делать yoursef http://pandas.pydata.org/pandas-docs/dev/r_interface.html

In [1217]: from pandas import DataFrame

In [1218]: df = DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7,8,9]},
   ......:                index=["one", "two", "three"])
   ......:

In [1219]: r_dataframe = com.convert_to_r_dataframe(df)

In [1220]: print type(r_dataframe)
<class 'rpy2.robjects.vectors.DataFrame'>