按组转换数据

时间:2014-12-02 01:57:17

标签: r ggplot2

我想知道是否可以在执行分组后应用ggplot2转换(数据)

示例:

以下是iris种类的qqplot:

ggplot(iris, aes(sample=Sepal.Width, col=Species)) +
    stat_qq() +
    ggtitle('qqnorm of Sepal Width')

qqnorm raw sepal width

我想通过Sepal.Width转换(x - mean(x))/sd(x)

normalize = function (x) (x - mean(x))/sd(x)
ggplot(iris, aes(sample=normalize(Sepal.Width), col=Species)) +
    stat_qq() +
    ggtitle('qqnorm of Sepal Width, normalized globally')

qqnorm of sepal width, shifted/scaled by global mean/sd

请注意,这在规范化中使用了全局均值/ sd,而不是每组均值/ sd(如果您编写aes(sample=(Sepal.Width - mean(Sepal.Width))/sd(Sepal.Width))而不是将其隐藏在normalize中,则会发生相同的情况。

问题:有没有办法在 每个群组(物种)中应用normalize

我可以使用ddply进行操作,只是想知道是否有一种优雅的方法可以在ggplot调用中对我的数据应用仿射变换,其中转换参数是按组的。

ggplot(ddply(iris, .(Species), mutate, y=normalize(Sepal.Width)),
             aes(sample=y, col=Species)) +
    stat_qq() +
    ggtitle('qqnorm of Sepal.Width, normalized within-group')

qqnorm I'm after

1 个答案:

答案 0 :(得分:1)

您也可以更改功能normalize以获取智能by。这使normalize函数更复杂,但简化了ggplot调用(与plyr解决方案相比)。请参阅下文,了解有关如何定义规范化的建议。

# new normalize command
normalize <- function(x, by='none'){
  unsplit(lapply(unique(by), function(id) scale(x[by==id])), by)
} 
# global normalization
ggplot(iris, aes(sample=normalize(Sepal.Width), col=Species)) +
  stat_qq() +
  ggtitle('qqnorm of Sepal Width, normalized globally')
# groupe-wise normalization
ggplot(iris, aes(sample=normalize(Sepal.Width, by=Species), col=Species)) +
  stat_qq() +
  ggtitle('qqnorm of Sepal Width, normalized by species')