2014-12-02 4 views
4

Я хочу знать, можно ли применить ggplot2 преобразования (данных) после группировка была выполнена.Преобразование данных по группам

Пример:

Вот qqplot из iris по видам:

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

FYI: только что открытая встроенная функция 'scale':' scale (x) 'такая же, как моя' normalize (x) '. –

+0

Я не уверен, но: 'ggplot (iris, aes (sample = Sepal.Width, col = Виды)) + stat_qq (distribution = function (p) qnorm (scale (p)))'? –

+0

@BenBolker, к сожалению, нет, 'qnorm' берет в себя набор квантилей и возвращает нормальные значения (на« теоретической »оси). Мне нужно изменить ось «образец». Подозреваемый 'ddply' может оказаться в пути, тем больше я смотрю на него менее громоздким. –

ответ

0

Вы также можете просто изменить функцию 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') 
Смежные вопросы