【问题标题】:Changing factor order in ggplot2 with Rpy2 in Python在 Python 中使用 Rpy2 更改 ggplot2 中的因子顺序
【发布时间】:2013-02-22 20:30:21
【问题描述】:

我正在尝试将以下代码翻译成 Rpy2,但没有成功:

neworder <- c("virginica","setosa","versicolor")
library("plyr")
iris2 <- arrange(transform(iris,
             Species=factor(Species,levels=neworder)),Species)

这意味着只是更改特定列的factor 顺序,在本例中为Species

我也不想在 Rpy2 中使用 plyr 和所有这些东西,因为我可以修改绘制为 Python 对象的数据框。以下方法不起作用:

# start with Python df 'mydf' and convert to R df
# to get mydf_r. The column equivalent of Species here
# is "variable"
# ...
mydf_r.variable = r.factor(ro.StrVector(["a", "b", "c"]))
# call ggplot...
ggplot2.ggplot(mydf) + ...

这不起作用。如何获得等效的 R 代码? IE。我有一个融化的数据框,其中variable 的几个值绘制为c, b, a,我想通过更改variablefactor 顺序将顺序更改为a, b, c。谢谢。

edit我可以使用以下代码更改顺序:

labels = robj.StrVector(tuple(["a", "b", "c"]))
variable_factor = r.factor(labels, levels=labels)
r_melted = r.transform(r_melted, **{"variable": variable_factor})
p = ggplot2.ggplot(r_melted) + \
    ggplot2.geom_boxplot(aes_string(**{"x": "variable",
                                       "y": "value"
                                        "fill": "group"})) + \
    ggplot2.scale_fill_manual(values=np.array(["#00BA38", "#F8766D"])) + \
    ggplot2.coord_flip()

但是,这破坏了 ggplot 正确制作箱线图并通过group 变量对其进行颜色编码的能力。如果我删除这些行:

labels = robj.StrVector(tuple(["a", "b", "c"]))
variable_factor = r.factor(labels, levels=labels)
r_melted = r.transform(r_melted, **{"variable": variable_factor})

然后一切正常...我只想更改variable 值出现在箱线图中的顺序。

@lgautier:您提供的解决方案看起来像我想要的,但在这里对我不起作用。我用iris 数据集为它做了一个测试用例:

原图

import os
iris = pandas.read_table(os.path.expanduser("~/iris.csv"),
                         sep=",")
iris["Species"] = iris["Name"]
r_melted = conversion_pydataframe(iris)
p = ggplot2.ggplot(r_melted) + \
    ggplot2.geom_boxplot(aes_string(**{"x": "PetalLength",
                                       "y": "PetalWidth",
                                       "fill": "Species"})) + \
    ggplot2.facet_grid(Formula("Species ~ .")) + \
    ggplot2.coord_flip()
p.plot()

产生:

但如果我添加:

labels = robj.StrVector(tuple(["versicolor", "virginica", "setosa"]))
variable_i = r_melted.names.index("Species")
r_melted[variable_i] = robj.FactorVector(r_melted[variable_i],
                                         levels=labels)

在绘图之前,我得到:

我认为这是因为我使用的名称与 Species 名称值不完全匹配。如果 rpy2 在发生这种情况时引发错误,那将很有帮助。但无论如何,如果我想覆盖因子的名称怎么办? IE。取第一个因素名称并使其成为x,第二个y 等,并按该顺序显示?这样做的唯一方法是在数据框中使用正确的名称为其创建一个新列吗?

【问题讨论】:

  • 更改级别的标签是一个不同的问题。您可以在创建因子时 (FactorVector(['a','b','c'], labels=StrVector(['Le A','Le B','Le C']))) 或创建因子后 (f = FactorVector(['a', 'b', 'c']); f.levels[0] = 'A') 执行此操作
  • 您获得了一个灰色框,因为级别不对应于向量中的任何标签。没有警告,因为在这种情况下 R 不会产生警告(在 R 中尝试:factor(c("a", "b", "c"), levels = c("A")))。我认为,其逻辑是假设,如果明确指定级别,则不匹配的级别应标记为“NA”。 `

标签: python ggplot2 rpy2


【解决方案1】:

您需要即时更改所用因子的级别(下面的第一个示例),或者在数据框的列中更改(第二个示例)。

如果labels 是一个相对较短的列表,则以下将起作用:

# r_melted is the one defined upstream of your code snippet,
# not the results of calling r.transform()
labels = robj.StrVector(tuple(["a", "b", "c"]))
p = ggplot2.ggplot(r_melted) + \
    ggplot2.geom_boxplot(aes_string(**{"x": "factor(variable, levels = %s)" % labels,
                                       "y": "value"
                                       "fill": "group"})) + \
    ggplot2.scale_fill_manual(values=np.array(["#00BA38", "#F8766D"])) + \
    ggplot2.coord_flip()

如果labels 更大(或根本不需要 R 代码):

# r_melted is the one defined upstream of your code snippet,
# not the results of calling r.transform()
from rpy2.robjects.vectors import FactorVector
variable_i = r_melted.names.index('variable')
r_melted[variable_i] = FactorVector(r_melted[variable_i],
                                    levels = robj.StrVector(tuple(["a", "b", "c"]))
p = ggplot2.ggplot(r_melted) + \
    ggplot2.geom_boxplot(aes_string(**{"x": "variable",
                                       "y": "value"
                                       "fill": "group"})) + \
    ggplot2.scale_fill_manual(values=np.array(["#00BA38", "#F8766D"])) + \
    ggplot2.coord_flip()

【讨论】:

  • 谢谢。更一般地说,是否需要像上面的原始代码一样从 Rpy2 调用plyr?或者是否可以/最好总是在 Python 中进行这些数据帧操作,然后在准备绘图时将结果转换为 R 数据帧?
  • 不幸的是,这两种方法都不适合我——我用我得到的输出的详细示例编辑了我的帖子。有什么想法吗?
  • @user248237dfsf:我想说:从你最喜欢的方式开始。如果您习惯的方法导致看似过于复杂的代码或性能问题,那么您仍然可以尝试其他方式。
  • @user248237dfsf:我希望这些方法有效。显然,级别必须对应于因子中的标签(在您的附加示例中,即“Iris-versicolor”、“Iris-virginica”和“Iris-setosa”;而不是“versicolor”、“virginica”和“setosa”)。
猜你喜欢
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 2012-04-10
  • 1970-01-01
  • 2014-08-28
相关资源
最近更新 更多