我在R中有一个data.frame。它包含很多数据:来自许多(125)数组的基因表达水平。我想要Python中的数据,主要是因为我在R中的无能,以及这应该是一个30分钟的工作。
我希望以下代码能够正常运行。要理解此代码,请知道变量path
包含数据集的完整路径,在加载时,它会为我提供一个名为immgen
的变量。知道immgen
是一个对象(Bioconductor ExpressionSet
对象),exprs(immgen)
返回一个包含125列(实验)和数万行(命名基因)的数据框。 (以防万一它不清楚,这是Python代码,使用robjects.r来调用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)
此代码会运行,但expression_data
只是array([[1]])
。
我非常确定e
不代表exprs()
生成的数据框,原因如下:
In [40]: e._get_ncol()
Out[40]: 1
In [41]: e._get_nrow()
Out[41]: 1
但是又有谁知道呢?即使e
确实代表我的data.frame,它不直接转换为数组也足够公平 - 数据框中的数据框比数组(rownames和colnames)更多,所以也许生活不应该'这很容易。但是我仍然无法弄清楚如何执行转换。文档对我来说有点过于简洁,尽管我对文档中标题的有限理解意味着这应该是可能的。
有人有什么想法吗?
答案 0 :(得分:7)
这是我发现将数据帧从R传输到Python的最简单可靠的方法。
首先,我认为通过R绑定交换数据是一种不必要的复杂问题。 R提供了一种简单的方法来导出数据,同样,NumPy有很好的数据导入方法。文件格式是此处所需的唯一通用接口。
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. ]]
根据文档(以及我自己的经验, loadtxt 是传统数据导入的首选方法。
您还可以传入 loadtxt 一个数据类型元组(参数为 dtypes ),每个列的元组中有一个项目。注意'skiprows = 1'来跳过列标题(对于 loadtxt 行是从1开始索引,从0开始的列)。
最后,我在导出之前将数据帧因子转换为整数(实际上是因子的基础数据类型) - 'unclass'可能是最简单的方法。
如果您有大数据(即,不想将整个数据文件加载到内存中但仍需要访问它) NumPy的内存映射数据结构('memmap')是一个不错的选择:
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 :(得分:4)
当'exprs(immgen)'返回/ matrix /时,为什么要通过data.frame,你的最终目标是将数据放在矩阵中?
将矩阵传递给numpy很简单(甚至可以不制作副本): http://rpy.sourceforge.net/rpy2/doc-2.1/html/numpy.html#from-rpy2-to-numpy
这应该简单而有效地打破了在平面文件中通过数字数据的文本表示作为交换数据的方式的建议。
您似乎正在使用bioconductor类,可能对以下内容感兴趣: http://pypi.python.org/pypi/rpy2-bioconductor-extensions/