我正在尝试找到一个R代码,用于使用两列矩阵的最小值和最大值对我的值进行归一化。
我的矩阵看起来像这样:第一列(C1)和C2 I.D不计算,C3;标题行1,然后是407数字和NA,C4;标题行1,然后是数字和NA。
我在想像这样的东西:
C3 = x的最小值,同一列x的最大值,
If(x="","NA",(x-Min value)/(Max value-Min value))这将给出一个值从0到1的列。应该对第4列执行同样的操作(这对于R来说是y还是令人困惑?)
我在编程或R方面不够熟练,不能生成这段代码,有没有专门的代码,或者有人能帮我写一个?
发布于 2012-10-19 17:04:43
给出您所描述的一些示例数据
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,我们必须处理这一点。您可能已经注意到,我在normalise()函数中将na.rm参数设置为TRUE。这意味着即使在存在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.607978R> apply(d3[, 3:4], 2, normalise)
C3 C4
[1,] NA NA
[2,] 0 1
[3,] NA NA
[4,] 1 0如果我们在编写normalise()时没有这样做,那么输出将如下所示(na.rm = FALSE是range()和其他类似函数的默认设置!)
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-19 15:58:18
这是一种非参数归一化,但我建议您使用另一种方法:计算中位数和四分位数范围,减去中位数并除以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] )https://stackoverflow.com/questions/12969623
复制相似问题