2010-04-19 43 views
7

Tôi có một data.frame trong R. Nó chứa rất nhiều dữ liệu: mức biểu hiện gen từ nhiều (125) mảng. Tôi muốn dữ liệu bằng Python, chủ yếu là do sự thiếu năng lực của tôi trong R và thực tế rằng điều này được cho là một công việc 30 phút.rpy2: Chuyển đổi một data.frame thành mảng có nhiều mảng

Tôi muốn mã sau hoạt động. Để hiểu mã này, hãy biết rằng biến số path chứa đường dẫn đầy đủ đến tập dữ liệu của tôi, khi được tải, cung cấp cho tôi một biến được gọi là immgen. Biết rằng immgen là một đối tượng (đối tượng Bioconductor ExpressionSet) và rằng exprs(immgen) trả về một khung dữ liệu với 125 cột (thử nghiệm) và hàng chục nghìn hàng (các gen được đặt tên). (Chỉ trong trường hợp nó không rõ ràng, đây là mã Python, sử dụng robjects.r để gọi mã R)

import numpy as np 
import rpy2.robjects as robjects 
# ... some code to build path 
robjects.r("load('%s')"%path) # loads immgen 
e = robjects.r['data.frame']("exprs(immgen)") 
expression_data = np.array(e) 

Mã này chạy, nhưng chỉ đơn giản là expression_dataarray([[1]]).

Tôi khá chắc chắn rằng e không đại diện cho khung dữ liệu được tạo ra bởi exprs() do những thứ như:

In [40]: e._get_ncol() 
Out[40]: 1 

In [41]: e._get_nrow() 
Out[41]: 1 

Nhưng sau đó một lần nữa ai mà biết được? Thậm chí nếu e đại diện cho data.frame của tôi, nó không chuyển đổi thẳng thành một mảng sẽ đủ công bằng - một khung dữ liệu có nhiều hơn một mảng (tên và tên) và vì vậy có lẽ cuộc sống không dễ dàng như vậy . Tuy nhiên tôi vẫn không thể tìm ra cách thực hiện chuyển đổi. Các tài liệu là một chút quá terse cho tôi, mặc dù sự hiểu biết hạn chế của tôi về các tiêu đề trong các tài liệu ngụ ý rằng điều này nên có thể.

Bất kỳ ai có suy nghĩ?

Trả lời

4

Tại sao phải thông qua một data.frame khi 'exprs (immgen)' trả về ma trận/và mục tiêu cuối cùng của bạn là có dữ liệu trong ma trận?

Đi qua ma trận để NumPy là đơn giản (và thậm chí có thể được thực hiện mà không cần tạo một bản sao): http://rpy.sourceforge.net/rpy2/doc-2.1/html/numpy.html#from-rpy2-to-numpy

này nên đánh bại ở cả hai sự đơn giản và hiệu quả đề nghị đi qua đại diện văn bản của dữ liệu số trong các tập tin phẳng như một cách để trao đổi dữ liệu.

Bạn dường như được làm việc với các lớp bioconductor, và có thể quan tâm như sau: http://pypi.python.org/pypi/rpy2-bioconductor-extensions/

+0

argh bạn đúng.Nó là một ma trận.Đó là rực rỡ, cảm ơn.Chỉ cần giải pháp là rõ ràng, tôi có thể làm: e = np .array (robjects.r ('exprs (immgen)')) và bây giờ e là một mảng numpy với tất cả các số dấu chấm động của tôi trong nó.Cảm ơn Laurent! Tôi quan tâm đến các công cụ bioC rpy2, nhưng không thể có được nó Một câu hỏi cho danh sách hỗ trợ mặc dù có thể ... –

7

Đây là cách đơn giản và đáng tin cậy nhất mà tôi đã tìm thấy để chuyển khung dữ liệu từ R sang Python.

Để bắt đầu, tôi nghĩ rằng trao đổi dữ liệu thông qua các ràng buộc R là một biến chứng không cần thiết. R cung cấp một phương thức đơn giản để xuất dữ liệu, tương tự như vậy, NumPy có các phương thức phong nha để nhập dữ liệu. Định dạng tệp là giao diện phổ biến duy nhất được yêu cầu ở đây.

data(iris) 
iris$Species = unclass(iris$Species) 

write.table(iris, file="/path/to/my/file/np_iris.txt", row.names=F, sep=",") 

# now start a python session 
import numpy as NP 

fpath = "/path/to/my/file/np_iris.txt" 

A = NP.loadtxt(fpath, comments="#", delimiter=",", skiprows=1) 

# print(type(A)) 
# returns: <type 'numpy.ndarray'> 

print(A.shape) 
# returns: (150, 5) 

print(A[1:5,]) 
# returns: 
[[ 4.9  3.   1.4  0.2  1. ] 
    [ 4.7  3.2  1.3  0.2  1. ] 
    [ 4.6  3.1  1.5  0.2  1. ] 
    [ 5.   3.6  1.4  0.2  1. ]] 

Theo tài liệu (và kinh nghiệm của riêng mình cho những gì nó có giá trị) loadtxt là phương pháp thuận lợi nhất để nhập dữ liệu thông thường.

Bạn cũng có thể vượt qua trong để loadtxt một tuple của các kiểu dữ liệu (các đối số là dtypes), một mục trong tuple cho mỗi cột. Lưu ý 'skiprows = 1' để vượt qua các tiêu đề cột (cho loadtxt hàng được lập chỉ mục từ 1, cột từ 0).

Cuối cùng, tôi đã chuyển đổi hệ số dữ liệu thành số nguyên (thực ra là kiểu dữ liệu cơ bản cho yếu tố) trước khi xuất - 'unclass' có lẽ là cách dễ nhất để thực hiện việc này.

Nếu bạn có dữ liệu lớn (tức là, không muốn để tải toàn bộ tập tin dữ liệu vào bộ nhớ nhưng vẫn cần phải truy cập vào nó) cấu trúc dữ liệu bộ nhớ ánh xạ NumPy của ('memmap') là một lựa chọn tốt:

from tempfile import mkdtemp 
import os.path as path 

filename = path.join(mkdtemp(), 'tempfile.dat') 

# now create a memory-mapped file with shape and data type 
# based on original R data frame: 
A = NP.memmap(fpath, dtype="float32", mode="w+", shape=(150, 5)) 

# methods are ' flush' (writes to disk any changes you make to the array), and 'close' 
# to write data to the memmap array (acdtually an array-like memory-map to 
# the data stored on disk) 
A[:] = somedata[:] 
+1

Cảm ơn Doug! Đây là giải pháp tôi đã giải quyết quá - vấn đề duy nhất là các tập tin kết quả là + 50MB đó là loại OK, nhưng có vẻ như một liên lạc clunky! Tôi muốn các ràng buộc rpy2 để cho tôi viết một hàm có nghĩa là 'mảng, colnames, rownames = from_df (" data.frame() "'. –

+1

trong trường hợp đó (dữ liệu lớn) tôi sẽ chỉ sử dụng dữ liệu được ánh xạ bộ nhớ của NumPy cấu trúc, để tránh tải toàn bộ điều vào RAM.Chỉnh sửa câu trả lời của tôi w/ví dụ – doug

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