有没有一种方法可以在Python/rpy2中访问R数据框列名?

7

我有一个R数据框,在Database02.Rda中保存。加载它。

import rpy2.robjects as robjects
robjects.r.load("Database02.Rda")

工作得很好。然而:

print(robjects.r.names("df"))

产量
NULL

此外,以列214(如果我们从0开始计数,则为213)为例,其名称为REGION。
print(robjects.r.table(robjects.r["df"][213]))

运行正常:

Region 1   Region 2   ...
    9811       3451   ...

但我们也应该能够做到。
print(robjects.r.table("df$REGION"))

然而,这会导致...
df$REGION 
        1

(它也会对根本不存在的列名进行操作);另外:
print(robjects.r.table(robjects.r["df"]["REGION"]))

出现错误:

TypeError: SexpVector indices must be integers, not str

现在,文档中说,在Python中不能使用名称进行子集操作。我是否正确地认为,在使用Python/rpy2加载数据帧时,列名没有与其他数据一起导入?因此,最简单的访问方法是将它们保存并加载为单独的列表,并在Python中构建一个映射名称到列索引号的字典等。然而,这似乎不太通用。有没有直接提取列名的方法?
我使用的R、Python和rpy2版本是: R: 3.2.2 Python: 3.5.0 rpy2: 2.7.8
2个回答

5

在执行以下操作时,您将把Database02.Rda中的任何对象加载到R的“全局环境”中。

import rpy2.robjects as robjects
robjects.r.load("Database02.Rda")

robjects.globalenv 是一个 环境对象。您可以使用以下代码列出其内容:

tuple(robjects.globalenv.keys())

现在我理解你的其中一个对象被称为df。你可以通过以下方式访问它:

df = robjects.globalenv['df']

如果 df 是一个列表或数据框,你可以使用 rx2文档在这里帮助你)来访问其命名元素。要获取名为 REGION 的元素,请执行以下操作:

df.rx2("REGION")

要在列表或数据框中列出所有命名元素很容易:
tuple(df.names) 

谢谢您的回答。我想补充一点,df.rx2() 不会返回列本身的内容,而是用某种唯一标识符(介于1和该列中唯一元素数量之间的整数)替换它们。例如,robjects.r.head(df.rx("REGION")) 返回 [ 15, 18, 9, 15, 15, 15] 而不是 Region 1, Region 4, Region 9, Region 1, ...。即使对于具有 int 值的列也是如此,这使得任何数据分析都无法使用。事实上,我不知道 rx2() 方法是做什么的;我找不到帮助页面。 - 0range
这是一个因素和水平的问题,不一定存在于任何数据集中,但恰好出现在我的数据集中。对于我之前评论中的混淆表示抱歉。为了解决问题,请执行 as_character = robjects.r['as.character'] 然后执行 as_character(df.rx2("REGION")) 或者 as_character(robjects.r["df"][colnames.index("REGION")])。对于应该是数字的变量(在我的情况下,这个错误,将数值数据作为字符处理,“10”而不是10,已经在Rda文件中存在,我在此期间发现),请执行 as_numeric(as_character(df.rx2("NUMERIC_VAR"))) - 0range
R因子到Python的映射与R实现非常相似,但这并不是没有其独特之处。我认为,在仅使用R时也存在许多这样的问题,但可能有比rpy2当前处理方式更好的方法... - lgautier
1
@lgautier dfr = dfr.rx2(co) # where co = ["a", "b"] 对我来说不起作用。它应该吗?如果不是,那么我该如何按名称选择多列? - The Unfun Cat
使用随 rpy2 一起提供的转换规则,co 必须是 R 向量或 Python 标量类型之一,可以转换为 R 向量。使用 rpy2.robjects.vectors.StrVector 构建 co - lgautier

3
如果您在Python中运行R代码,则全局环境答案将无法正常工作。但是,感谢此软件包的创建者/维护者@lgautier。在R中,美元符号$经常被使用。这是我学到的:
print(pamk_clusters$pamobject$clusinfo)

将不起作用,其等效项

print(pamk_clusters[["pamobject"]][["clusinfo"]])

也不会起作用...然而,在“man”中进行了一些挖掘。

http://rpy2.readthedocs.io/en/version_2.7.x/vector.html#extracting-r-style

通过代表R函数 [ 和 [[ 的两个委托方 rx 和 rx2,授予对 R 风格提取/子集的访问权限。

这将按预期工作。

print(pamk_clusters.rx2("pamobject").rx2("clusinfo"))

我在论坛中评论了“man”的清晰度:

https://bitbucket.org/rpy2/rpy2/issues/436/acessing-dataframe-elements-using-rpy2

我正在使用rpy2在Win7上与ipython一起使用。为了帮助其他人更好地理解格式,这里提供一个似乎有效的设置:

import rpy2
import rpy2.robjects as robjects
import rpy2.robjects.packages as rpackages
from rpy2.robjects.packages import importr

base = importr('base')
utils = importr('utils')
utils.chooseCRANmirror(ind=1)

cluster = importr('cluster')
stats = importr('stats')
#utils.install_packages("fpc")
fpc = importr('fpc')

import pickle
with open ('points', 'rb') as fp:
    points = pickle.load(fp) 
# data above is stored as binary object
# online:  http://www.mshaffer.com/arizona/dissertation/points

import rpy2.robjects.numpy2ri as npr   
npr.activate()

k = robjects.IntVector(range(3, 8))   # r-syntax  3:7   # I expect 5
pamk_clusters = fpc.pamk(points,k)

print( base.summary(pamk_clusters) )
base.print( base.summary(pamk_clusters) )

utils.str(pamk_clusters)

print(pamk_clusters$pamobject$clusinfo)
base.print(pamk_clusters$pamobject$clusinfo)

print(pamk_clusters[["pamobject"]][["clusinfo"]])
print(pamk_clusters.rx2("pamobject").rx2("clusinfo"))

pam_clusters = cluster.pam(points,5)        # much slower
kmeans_clusters = stats.kmeans(points,5)    # much faster

utils.str(kmeans_clusters)

print(kmeans_clusters.rx2("cluster"))

R已经成为近25年的统计计算标准,基于40年前的S——当时计算效率非常重要。 https://en.wikipedia.org/wiki/R_(programming_language)

再次感谢@lgautier,使R在Python中更易于访问。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接