在 R 中使用 plyr (ddply) 重新缩放技巧

Trick rescaling with plyr (ddply) in R

我有这个 csv table,我需要在每列 0 到 1 之间重新缩放数据。也就是说,任何给定列的最低值为 0,最高值为 1,所有其他值将相应地线性缩放。这是我的脚本:

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))

问题是第 1 段不完全正确:重新缩放应该按列进行,最后两列除外:我需要 "E.e" 和 "F.f" 一起重新缩放到两列的最低值,和两列的最高值。也就是说,仅针对这些列而不是其他列,最低值应为 7(显示为白色),最高值应为 90(显示为深蓝色)。

因此,在 F.f 列中,所有单元格都应显示为深蓝色。

是否可以使用 plyr 实现此目的?

(在此示例中,B 列应显示为 2.13 为白色,1.88 为深蓝色,2.07、2.09、2.05 的阴影相应缩放。另一列应保持不变。)

您可以使用 ifelse 语句根据 E.eF.f 值的组合范围而不是每组值的范围来缩放 E.eF.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)))

更新: 看到您的评论后,我意识到我的原始代码不正确。我们要求 plyrvariable 分组,因此它无法同时查看 variable 的两个独立值来获得 rescale 的正确范围。

这是从完整数据框中获取正确范围的更新代码。它有效,但它是通过 "outside" 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)))

我知道你要求 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))