【问题标题】:Trick rescaling with plyr (ddply) in R在 R 中使用 plyr (ddply) 重新缩放
【发布时间】:2015-05-26 19:15:42
【问题描述】:

我有这个 csv 表,我需要在每列的 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))

问题在于第一段并不完全正确:除最后两列外,应按列进行重新调整:我需要根据最低值一起重新调整“E.e”和“F.f”两列,以及两列中的最大值。也就是说,仅对于这些列,而不是其他列,最低值应为 7(显示为白色),最高值应为 90(显示为深蓝色)。

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

有没有可能用 plyr 做到这一点?

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

【问题讨论】:

    标签: r plyr


    【解决方案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)))
    

    更新:看到您的评论后,我意识到我的原始代码不正确。我们已经要求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)))
    

    【讨论】:

    • 谢谢eipi10!不过很奇怪,它似乎对我不起作用。你试过了吗?
    • 是的。为我工作。你得到什么结果?在您的数据框中使用E.e F.f 与E..e. F..f. 是否存在问题?我删除了我的数据框版本中的额外句点,因为您在问题中称它们为 E.e 和 F.f,但额外的句点仍然存在于您的代码中。
    • 我得到这个:dropbox.com/s/0xoatbfgfnatypo/… 例如,第 19 行不应该是 1,第 22 行不应该是 0。
    • 我想知道我是否应该问另一个问题:如果我还需要选择其他列,是否可以合并多个 ifelse 请求:gist.github.com/anonymous/646107c1fb5694eb7f68?
    • 您可以嵌套ifelse 来处理多个选项,但您可能会发现使用switch function 更容易。
    【解决方案2】:

    我知道您要求的是 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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      • 2015-05-12
      • 2016-01-09
      • 1970-01-01
      相关资源
      最近更新 更多