rpy2: преобразование data.frame в пустой массив - PullRequest
7 голосов
/ 19 апреля 2010

У меня есть data.frame в R. Он содержит много данных: уровни экспрессии генов из многих (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, то, что он не преобразуется прямо в массив, будет достаточно справедливо - во фрейме данных содержится больше, чем в массиве (имена строк и столбцов), и, возможно, жизнь не должна это легко. Однако я все еще не могу понять, как выполнить преобразование. Документация для меня немного лаконична, хотя мое ограниченное понимание заголовков в документах подразумевает, что это должно быть возможно.

У кого-нибудь есть мысли?

Ответы [ 2 ]

7 голосов
/ 19 апреля 2010

Это самый простой и надежный способ передачи фрейма данных из 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[:]
4 голосов
/ 20 апреля 2010

Зачем проходить через data.frame, когда 'exprs (immgen)' возвращает / matrix /, и ваша конечная цель - поместить ваши данные в матрицу?

Передача матрицы NumPy проста (и даже может быть сделана без копирования): http://rpy.sourceforge.net/rpy2/doc-2.1/html/numpy.html#from-rpy2-to-numpy

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

Похоже, вы работаете с классами биокондуктора и вас может заинтересовать следующее: http://pypi.python.org/pypi/rpy2-bioconductor-extensions/

...