2013-02-01 38 views
12

Tôi muốn sử dụng gấu trúc cho tất cả các phân tích của tôi cùng với một chút nhưng sử dụng Rpy2 để vẽ dữ liệu của tôi. Tôi muốn làm tất cả các phân tích bằng cách sử dụng các khung dữ liệu gấu trúc và sau đó sử dụng âm mưu đầy đủ của R thông qua rpy2 để vẽ chúng. py2, và đang sử dụng ipython để vẽ. Cách chính xác để làm điều này là gì?Làm thế nào để sử dụng các khung dữ liệu gấu trúc và các mảng có khối lượng trong Rpy2?

Gần như tất cả các lệnh tôi cố gắng không thành công. Ví dụ:

  • Tôi đang cố vẽ đồ thị giữa hai cột của một chú gấu trúc DataFrame df. Tôi muốn các nhãn của df được sử dụng trong trục x/y giống như sẽ được sử dụng nếu nó là một khung dữ liệu R. Có cách nào để làm việc này không? Khi tôi cố gắng làm điều đó với r.plot, tôi nhận được âm mưu này vô nghia:

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

sản lượng:

Out: rpy2.rinterface.NULL

dẫn đến cốt truyện:

enter image description here

Khi bạn c nhìn thấy, các nhãn rìu bị rối tung lên và nó không đọc nhãn rìu từ DataFrame như nó nên (trục X là cột a của df và trục Y là cột b).

  • Nếu tôi cố gắng để tạo ra một biểu đồ với r.hist, nó không hoạt động ở tất cả, năng suất các lỗi:

    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 
    

Và kết quả là âm mưu này:

enter image description here

Bất kỳ ý tưởng nào về lỗi có nghĩa là gì? Và một lần nữa ở đây, các trục là tất cả các messed lên và rải rác với dữ liệu vô nghĩa.

EDIT: Lỗi này chỉ xảy ra khi sử dụng ipython. Khi tôi chạy lệnh từ một tập lệnh, nó vẫn tạo ra âm mưu có vấn đề, nhưng ít nhất chạy không có lỗi. Nó phải là một cái gì đó sai trái với các lệnh gọi từ ipython.

  • Tôi cũng đã cố gắng để chuyển đổi các gấu trúc DataFrame df một R DataFrame theo khuyến cáo của poster dưới đây, nhưng điều đó không quá với lỗi này:

    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 
    

Làm thế nào tôi có thể nhận được những các tính năng vẽ sơ đồ cơ bản để làm việc trên Pandas DataFrame (với nhãn của các ô được đọc từ các nhãn của Pandas DataFrame), và cũng có thể chuyển đổi giữa một Pandas DF thành R DF để làm việc?

EDIT2: Đây là ví dụ hoàn chỉnh về tệp csv "test".txt"(http://pastebin.ca/2311928) và mã của tôi để trả lời @ bình luận dale của:

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) 

Cuộc gọi để vẽ cột của 'data.c2' thất bại, mặc dù data.c2 là một cột của một df gấu trúc và do đó cho Tôi sử dụng cuộc gọi activate() vì vậy tôi nghĩ rằng nó sẽ xử lý cột này như là một mảng numpy và âm mưu nó. Nếu tôi tải lên test.txt từ R dưới dạng một khung dữ liệu, tôi có thể plot() nó và vì khung dữ liệu của tôi đã được chuyển đổi từ gấu trúc thành R, có vẻ như nó cũng nên làm việc ở đây.

Khi tôi thử rmagic trong ipython, nó không kích hoạt cửa sổ âm mưu vì lý do nào đó, mặc dù nó không lỗi. I E. nếu tôi làm:

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) 

Không có lỗi, nhưng không có cửa sổ lô. Trong mọi trường hợp, tôi muốn dính vào rpy2 và không dựa vào rmagic nếu có thể.

Cảm ơn.

+0

bạn có thể xuất csv và nhập lại hoặc sử dụng rpy – locojay

+0

@locojay: Làm thế nào để sử dụng rpy với khung dữ liệu gấu trúc? – user248237dfsf

+0

hãy xem http://rpy.sourceforge.net/rpy/doc/rpy_html/DataFrame-class.html trong đó sử dụng ds python std ... có cách tiếp cận tương tự bằng cách sử dụng gấu trúc df – locojay

Trả lời

7

[lưu ý: Mã của bạn trong "chỉnh sửa 2" đang làm việc ở đây (Python 2.7, rpy2-2.3.2, R-1.15.2).]

Như @dale đề cập đến nó bất cứ khi nào đối tượng R ẩn danh (không có biểu tượng R cho đối tượng) R deparse(substitute()) sẽ kết thúc trả về structure() của đối tượng R và sửa lỗi có thể là chỉ định tham số "xlab" và "ylab"; đối với một số ô, bạn cũng sẽ phải chỉ định main (tiêu đề).

Một cách khác để giải quyết vấn đề đó là sử dụng công thức của R và nạp khung dữ liệu (bên dưới, sau khi chúng tôi thực hiện phần chuyển đổi).

Hãy quên nội dung nằm trong số pandas.rpy. Nó là cả hai bị hỏng và dường như bỏ qua các tính năng có sẵn trong rpy2.

Trước đó, quick fix to conversion with ipython có thể được chuyển thành một chuyển đổi thích hợp khá dễ dàng.Tôi đang xem xét thêm một cho codebase rpy2 (với nhiều chuông và còi), nhưng trong khi chờ đợi chỉ cần thêm đoạn sau sau khi tất cả nhập khẩu của bạn trong ví dụ mã của bạn. Nó sẽ chuyển đổi một cách minh bạch các đối tượng DataFrame của gấu trúc thành DataFrame của rpy2 bất cứ khi nào một cuộc gọi R được thực hiện.

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 

Bây giờ đoạn mã sau sẽ "chỉ làm việc":

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). 

Tôi cũng lưu ý rằng bạn đang nhập ggplot2, mà không sử dụng nó. Hiện tại, chuyển đổi sẽ phải được yêu cầu một cách rõ ràng. Ví dụ:

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

Mã của bạn không hoạt động tôi - đây là ví dụ hoàn chỉnh của tôi và đầu ra của nó http://pastebin.com/index/tAFG7dUV - nó bây giờ phàn nàn về datatype 'Series' không được chuyển đổi. Bất kỳ ý tưởng? – user248237dfsf

+0

Nếu tôi thêm 'activate()' nó hoạt động nhưng khi tôi thử nó cho một khung dữ liệu dài, lỗi 'rpy2.rinterface.RRuntimeError: Lỗi trong plot.window (...): cần các giá trị 'xlim' hữu hạn' xảy ra. Nó không bao giờ làm việc cho bất kỳ dataframe thực sự nào. – user248237dfsf

+0

Tôi phải chỉ xem xét cột gây lỗi đầu tiên và chuyển sang khi tôi sửa lỗi đó. Thông báo lỗi cho biết rpy2 không biết cách chuyển đổi các đối tượng của lớp 'pandas.core.series.Series'. Một 'elif isinstance (obj, pandas.core.series.Series):' trước 'else:' và mã chuyển đổi sẽ sửa chữa nó một cách bình thường. Kể từ khi chuyển đổi khung dữ liệu gấu trúc bây giờ là một phần của codebase rpy2 (sẽ được phát hành 2.3.3), đây là một báo cáo lỗi (https://bitbucket.org/lgautier/rpy2/issue/118/converion-of- pandas-series-missing). – lgautier

5

sử dụng rpy. việc chuyển đổi là một phần của gấu trúc, do đó bạn không cần phải làm điều đó 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'> 
+3

chúng tôi đã thêm vào 0.10.1 khả năng xuất trong HDFStore, để rhdf5 có thể đọc - xem http://pandas.pydata.org/pandas-docs/stable/io.html#external-compatibility – Jeff

+0

Điều này thực sự không hoạt động ... Tôi nhận được: '' 275 # FIXME: Điều này không xử lý MultiIndex -> 277 cho cột trong df: 278 giá trị = df [cột] 279 value_type = value.dtype.type'' – user248237dfsf

+0

@Jeff: Chuyển đổi không hoạt động và nó quay ra ngay cả những lệnh rpy2 cơ bản nhất để R không hoạt động, xem các chỉnh sửa ở trên – user248237dfsf

6

Bạn cần phải vượt qua trong các nhãn rõ ràng khi gọi hàm r.plot.

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

Khi bạn cốt truyện trong R, nó grabs nhãn qua deparse(substitute(x)) trong đó chủ yếu lấy tên biến từ plot(testX, testY). Khi bạn đang truyền các đối tượng python qua rpy2, đó là một đối tượng R ẩn danh và giống như sau trong R:

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

đó là lý do tại sao bạn nhận được nhãn điên.

Rất nhiều lần bạn nên sử dụng rpy2 để chỉ đẩy dữ liệu qua lại.

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/

+0

Cảm ơn câu trả lời của bạn, nhưng làm thế nào tôi có thể gặp lỗi mà tôi nhận được khi cố gắng gọi '' com.convert_to_r_dataframe (mydf) ''? Điều đó dường như độc lập với vấn đề ghi nhãn lô hàng – user248237dfsf

+0

, làm thế nào để bạn xác định ''% R'' trong ipython? – user248237dfsf

+0

Đăng một ví dụ về khung dữ liệu hoặc sổ ghi chép. –

Các vấn đề liên quan