Group data conversion

I want to know if ggplot2 transforms (data) can be applied after grouping has been done.

Example:

Here is qqplot irisby type:

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

qqnorm raw sepal width

I want to convert Sepal.Widthto (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

Note that this used the global average / sd for normalization, not the average for the / sd group (this happens if you write aes(sample=(Sepal.Width - mean(Sepal.Width))/sd(Sepal.Width)), but don't hide it in normalize.

Question : is there a way of applying normalize within each group (Species)?

I can do this with ddplyjust thought if there is an elegant way to apply an affine transform to my data in a call ggplot, where the transform options are for each group.

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

+4
1

normalize, argent 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')
0

All Articles