2015-05-26 2 views
0

У меня есть эта таблица csv, для которой мне нужно перемасштабировать данные между 0 и 1 за каждый столбец. То есть наименьшее значение любого заданного столбца будет 0, наивысшее будет 1, и все остальные значения будут соответственно линейно масштабироваться. Вот мой сценарий:Trick rescaling с plyr (ddply) в R

tableau <- read.csv(text="Net,B,C,D,E (e),F (f) 
a,1.88,0.15,0.6,10,90 
b,2.05,0.23,0.51,55,80 
c,2.09,0.29,0.4,58,88 
d,2.07,0.52,0.36,80,84 
e,2.13,0.3,0.27,7,90") 
tableau.m <- melt(tableau) 
tableau.m <- ddply(tableau.m, .(variable), transform,rescale = rescale(value)) 

Вопрос заключается в том, что первый пункт не совсем верно: в перемасштабирует должно быть сделано по столбцам, за исключением двух последних столбцов, кроме: мне нужно «Ee» и «Ff», чтобы быть пересчитаны вместе в соответствии с наименьшим значением двух столбцов и наивысшим значением двух столбцов. То есть для этих столбцов, а не для других, самое низкое значение должно быть 7 (показывается как белый), а самое высокое должно быть 90 (отображается как темно-синий).

Итак, в столбце F.f все ячейки должны отображаться как темно-синий.

Можно ли достичь этого с помощью plyr?

enter image description here

(В этом примере, столбец В следует читать с 2.13 быть белыми, 1,88 быть темно-синим цветом, и 2,07-х, 2,09 х, 2,05 в оттенках масштабируются соответственно. Другой столбец должен быть остались нетронутыми)

ответ

1

Вы можете использовать ifelse заявление для масштабирования значений E.e и F.f на основе их комбинированного диапазона, а не в диапазоне от каждой группы значений:.

tableau.m = ddply(tableau.m, .(variable), transform, 
        rescale = ifelse(variable %in% c("E.e","F.f"), 
            rescale(value, 
              from=range(value[variable %in% c("E.e","F.f")])), 
            rescale(value))) 

UPDATE: После просмотра вашего комментария, я понял, что мой оригинальный код был неправильным. Мы попросили plyr сгруппировать по variable, поэтому он не может смотреть на два отдельных значения variable в то же время, чтобы получить правильный диапазон для rescale.

Вот обновленный код, который получает правильный диапазон из полного кадра данных. Он работает, но он делает это, переходя «вне» среду функции группировки plyr, которая не кажется мне очень изящной (и, возможно, даже может иметь непреднамеренные последствия в некоторых ситуациях).

tableau.m = ddply(tableau.m, .(variable), transform, 
        rescale=ifelse(variable %in% c("E.e","F.f"), 
           rescale(value, 
             from=range(tableau.m$value[tableau.m$variable %in% c("E.e","F.f")])), 
           rescale(value))) 
+0

Благодаря eipi10! Странно, но, похоже, это не работает на моей стороне. Ты это пробовал? – Rodolphe

+0

Да. Работает на меня. Какой результат вы получаете? Это вопрос использования 'E.e F.f' против' E..e. F..f.' в вашем кадре данных? Я избавился от дополнительных периодов в моей версии фрейма данных, так как вы вызывали их 'E.e' и' F.f' в своем вопросе, но дополнительные периоды все еще присутствуют в вашем коде. – eipi10

+0

Я получаю это: https://www.dropbox.com/s/0xoatbfgfnatypo/Capture%20d%27%C3%A9cran%202015-05-27%2011.01.40.png?dl=0 Например, строка 19 не должна быть 1, а строка 22 не должна быть 0. – Rodolphe

1

Я понимаю, что вы просили plyr ответ, но вот dplyr один за другим, которые приходят ищет:

library(dplyr) 
library(scales) 
library(tidyr) 

tableau %>% 
    mutate_each(funs(rescale), B, C, D) %>% 
    mutate_each(funs(rescale(., from=range(tableau[,5:6]))), 5, 6) %>% 
    gather(variable, rescale, -Net) %>% 
    left_join(gather(tableau, variable, value)) 
Смежные вопросы