【问题标题】:Rpy2: How to convert list of dictionaries to R data frameRpy2:如何将字典列表转换为 R 数据框
【发布时间】:2023-07-24 11:33:01
【问题描述】:

我有一个 Python 字典列表如下(来自 sqlite3 行工厂):

obs = [{'ave': 0.027, 'pap': 0.277}, 
{'ave': 0.29, 'pap': 0.333}, 
{'ave': 0.25, 'pap': 0.5}]

我想将其转换为 R data.frame 以便与rpy2(版本 2.3.6)一起使用,使其看起来像这样

    ave   pap  

1 0.027 0.277 
2 0.29  0.333
3 0.25  0.5

我能够将单个“行”转换为 data.frame,如下所示:

robjects.DataFrame(obs[0])

    ave   pap 

1 0.027 0.277 

使用robjects.DataFrame(obs) 不起作用... ValueError: obj 可以是可迭代类的实例(例如 Python dict、rpy2.rlike.container OrdDict 或 rpy2.rinterface.SexpVector 类型的实例VECSXP

我也尝试使用 rpy2.rlike.container.OrdDict(obs) 将其转换为 OrdDict,但得到 ValueError: too many values to unpack

我认为有许多不同的技术可以实现这一点,而 rpy2 和 Python 中的大量数据结构让我感到困惑。

【问题讨论】:

    标签: python r dictionary rpy2


    【解决方案1】:

    [回答问题和接受的答案]

    当 obs 变大时,创建 R 数据帧并附加它们会导致性能问题。 解决此问题的一种方法是在 Python 中“转置”结果。

    # "transpose" the data structure in Python
    from collections import defaultdict
    d = defaultdict(list)
    for row in obs:
        for colname in row:
            d[colname].append(row[colname])
    
    # Assuming that all data are floats
    # (if not the case a mapping between SQLite3 types and R vector types is needed)
    for rpy2.robjects.vectors import FloatVector
    for colname in d:
        d[colname] = FloatVector(d[colname])
    
    # data frame
    from rpy2.robjects import DataFrame
    dataf = DataFrame(d)
    

    【讨论】:

      【解决方案2】:

      我实际上找到了一个答案(这可能不是最有效的,但对我有用):

      在 Python 中:

      df = robjects.DataFrame(obs[0])
      for ob in obs[1:]:
          df = df.rbind(robjects.DataFrame(ob))
      

      如果有人有更好、更优雅、更高效的解决方案,欢迎发布。

      【讨论】: