2

我试图找到一个 R 代码,用于使用两列矩阵的最小值和最大值对我的值进行归一化。

我的矩阵如下所示: 第一列 (C1) 和 C2 ID 不计算,C3;标题第 1 行,然后是 407 个数字和 NA,C4;标题第 1 行,然后是数字和 NA。

我在想类似的东西:

C3 = x 的最小值,同一列 x 的最大值,

If(x="","NA",(x-Min value)/(Max value-Min value))

这将给出一个值从 0 到 1 的列。对第 4 列也应该这样做(是 y 还是这对 R 来说很混乱?)

我在编程或 R 语言方面不够熟练,无法生成此代码,是否有专门的代码,或者任何人都可以帮我写一个?

4

2 回答 2

4

给定一些示例数据,沿着您描述的路线

set.seed(1)
d <- data.frame(C1 = LETTERS[1:4], C2 = letters[1:4],
                C3 = runif(4, min = 0, max = 10),
                C4 = runif(4, min = 0, max = 10))
d

然后我们可以写一个简单的函数来做你描述的规范化

normalise <- function(x, na.rm = TRUE) {
    ranx <- range(x, na.rm = na.rm)
    (x - ranx[1]) / diff(ranx)
}

这可以通过多种方式应用于数据,但在这里我使用apply()

apply(d[, 3:4], 2, normalise)

这使

R> apply(d[, 3:4], 2, normalise)
            C3        C4
[1,] 0.0000000 0.0000000
[2,] 0.1658867 0.9377039
[3,] 0.4782093 1.0000000
[4,] 1.0000000 0.6179273

要将这些添加到现有数据中,我们可以这样做:

d2 <- data.frame(d, apply(d[, 3:4], 2, normalise))
d2

这使:

R> d2
  C1 C2       C3       C4      C3.1      C4.1
1  A  a 2.655087 2.016819 0.0000000 0.0000000
2  B  b 3.721239 8.983897 0.1658867 0.9377039
3  C  c 5.728534 9.446753 0.4782093 1.0000000
4  D  d 9.082078 6.607978 1.0000000 0.6179273

现在您提到您的数据包括NA,我们必须处理它。您可能已经注意到我在函数中将na.rm参数设置为。这意味着即使在以下情况下它也可以工作:TRUEnormalise()NA

d3 <- d
d3[c(1,3), c(3,4)] <- NA ## set some NA
d3


R> d3
  C1 C2       C3       C4
1  A  a       NA       NA
2  B  b 3.721239 8.983897
3  C  c       NA       NA
4  D  d 9.082078 6.607978

我们仍然得到normalise()一些有用的输出,只使用非NA数据:

R> apply(d3[, 3:4], 2, normalise)
     C3 C4
[1,] NA NA
[2,]  0  1
[3,] NA NA
[4,]  1  0

如果我们没有以书面形式执行此操作normalise(),那么输出将如下所示(na.rm = FALSErange()和其他类似函数的默认值!)

R> apply(d3[, 3:4], 2, normalise, na.rm = FALSE)
     C3 C4
[1,] NA NA
[2,] NA NA
[3,] NA NA
[4,] NA NA
于 2012-10-19T09:04:42.977 回答
0

这是一种非参数标准化,但我建议您使用另一种方法:计算中位数和四分位数范围,减去中位数并除以 IQR。这将为您提供中位数为 0 且 IQR 为 1 的分布。

m <- median( df$C3, na.rm = T )
iqr <- IQR( df$C3, na.rm = T )
df$C3 <- ( df$C3 - m ) / iqr

您提出的方法对异常值非常敏感。如果你真的想这样做,可以这样做:

 rng <- range( df$C3, na.rm = T )
 df$C3 <- ( df$C3 - rng[1] ) / ( rng[2] - rng[1] )
于 2012-10-19T07:58:17.683 回答