Rpy2 pandas2ri.ri2py() 正在将 NA 值转换为整数

Rpy2 pandas2ri.ri2py() is converting NA values to integers

我将 Rpy2 版本 2.8.4 与 R 3.3.0 和 python 2.7.10 结合使用来创建 R 数据帧

import rpy2.robjects as ro
from rpy2.robjects import r
from rpy2.robjects import pandas2ri

df = ro.DataFrame({'Col1': ro.vectors.IntVector([1, 2, 3, 4, 5]),
               'Col2': ro.vectors.StrVector(['a', 'b', 'c', 'd', 'e']),
               'Col3': ro.vectors.FactorVector([1, 2, 3, ro.NA_Integer, ro.NA_Integer])})
print df

   | Col2 | Col3 | Col1 |
   ----------------------
 1 |  a   | 1    | 1    |
 2 |  b   | 2    | 2    |
 3 |  c   | 3    | 3    |
 4 |  d   | NA   | 4    |
 5 |  e   | NA   | 5    |

我可以毫无困难地将其转换为 pandas 数据框。

pandas2ri.ri2py(df)

   | Col2 | Col3 | Col1 |
   ----------------------
 1 |  a   | 1    | 1    |
 2 |  b   | 2    | 2    |
 3 |  c   | 3    | 3    |
 4 |  d   | NA   | 4    |
 5 |  e   | NA   | 5    |

但是,我注意到 FactorVector 元数据包括 'NA' 作为因子级别,

print r('levels(df$Col3)')

[1] "1"  "2"  "3"  "NA"

据我所知,这在创建 factors in R 时不是默认行为。

如果我从因子水平中降低 'NA',

r.assign('df', df)
r('df$Col3 <- factor(as.numeric(levels(df$Col3))[df$Col3])')

然后我在将 R 数据帧转换为 pandas 数据帧时得到非常不同的结果。

df2 = r['df']
pandas2ri.ri2py(df2)

   | Col2 | Col3 | Col1 |
   ----------------------
 1 |  a   | 1    | 1    |
 2 |  b   | 2    | 2    |
 3 |  c   | 3    | 3    |
 4 |  d   | 1    | 4    |
 5 |  e   | 1    | 5    |

我的问题是这是否是一个错误,或者我假设 NA_Integer 值不应作为 R 数据帧中的因子水平包含在内是不是做错了什么?

正在将 R data.frame 中的一列因子转换为 pandas DataFrame 中的一列 with that code。没有以特定方式处理 NA,因此这必须发生在转换的上游。如果您查看您的专栏 "Col3",您会发现 NA 已列为因子中的水平。

>>> print(df.rx2("Col3"))
[1] 1  2  3  NA NA
Levels: 1 2 3 NA

这甚至在创建 R data.frame:

的上游
>>> lst = [1, 2, 3, ro.NA_Integer, ro.NA_Integer]
>>> print(ro.vectors.FactorVector(lst))
[1] 1  2  3  NA NA
Levels: 1 2 3 NA

发生的事情是 rpy2 中 FactorVector 的构造函数对参数 exclude 使用的默认值不同于 R 的 factor() 函数中的默认值(我认为它是这样做是为了使整数之间的映射默认用作级别向量的索引。

R 的默认行为可以通过以下方式恢复:

>>> v = ro.vectors.FactorVector(lst, exclude=ro.StrVector(["NA"]))
>>> print(v)
[1] 1    2    3    <NA> <NA>
Levels: 1 2 3

这里的问题是(在 IEEE 标准的意义上)没有表示缺失值的指南。 R 使用任意极值,但 Python 没有缺失值的概念。