为什么R中的sd返回矩阵输入的向量,我该怎么办呢?

时间:2011-08-21 03:59:19

标签: r

我有点困惑为什么R中的sd函数返回一个矩阵输入数组(我想保持向后兼容性,它总是会这样)。这对我来说是非常奇怪的行为:

#3d input, same same
print(length(mean(array(rnorm(60),dim=c(3,4,5)))))
print(length(sd(array(rnorm(60),dim=c(3,4,5)))))
#1d input, same same
print(length(mean(array(rnorm(60),dim=c(60)))))
print(length(sd(array(rnorm(60),dim=c(60)))))
#2d input, different!
print(length(mean(array(rnorm(60),dim=c(12,5)))))
print(length(sd(array(rnorm(60),dim=c(12,5)))))

我得到了

[1] 1
[1] 1
[1] 1
[1] 1
[1] 1
[1] 5

当输入是2-d数组时,sdmean的行为不同(显然只是在那种情况下!)然后考虑,这个失败的函数重新缩放k-的每一列尺寸数组由标准差决定:

re.scale <- function(x) {
    #rescale by the standard deviation of each column
    scales <- apply(x,2,sd)
    ret.val <- sweep(x,2,scales,"/")
}

#this works just fine
x <- array(rnorm(60),dim=c(12,5))
y <- re.scale(x)

#this throws a warning
x <- array(rnorm(60),dim=c(3,4,5))
y <- re.scale(x)

如果没有这种奇怪的行为,还有其他一些函数可以替换sd吗?如何正确地写re.scale?或者Z-score-by-column功能?

2 个答案:

答案 0 :(得分:7)

它在sd的帮助页面中表现为文档。在最顶端,它宣布:

“如果x是矩阵或数据框,则返回列标准差的向量。”

请注意,它并未说明包含数组,因此仅包含具有两个维度的数组。如果你想要停止这种行为,那么只需用c():

创建一个向量
 sd( c(array(rnorm(60),dim=c(12,5))) )
 # [1] 0.9505643

我看到您添加了列z分数的请求。试试这个矩阵:

colMeans(x)/sd(x)

这适用于数组(虽然“列”的定义可能需要澄清:

apply(x, 2:3, mean)/apply(x, 2:3, sd)   # will generalize to higher dimensions

答案 1 :(得分:3)

改变了sd的行动:

1。版本2.13.2(2011-09-30)及更早版本

Welcome to the Java Conversion Calculator.
This program will convert feet to meters.
Enter the number of feet you need to convert: Exception in thread "main"
java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:862)
    at java.util.Scanner.next(Scanner.java:1485)
    at java.util.Scanner.nextFloat(Scanner.java:2345)
    at JavaConversionCalculator.main(JavaConversionCalculator.java:20)

描述

此函数计算x中值的标准偏差。如果 na.rm为TRUE,然后在计算之前删除缺失值 收益。 如果x是矩阵或数据帧,则是标准的向量 返回列的偏差

2。 R版本2.14.0(2011-10-31) - 2.15.3(2013-03-01)

> set.seed(1)
> sd(array(rnorm(60),dim=c(12,5))) 
[1] 0.8107276 1.1234795 0.7925743 0.6186082 0.9464160

详细

在R 2.14.0之前,sd(dfrm)直接为data.frame工作 DFRM。现在已弃用,您应该使用sapply(dfrm, SD)。

3。 R版本3.0.0(2013-04-03)及更高版本

> set.seed(1)
> sd(array(rnorm(60),dim=c(12,5))) 
[1] 0.8107276 1.1234795 0.7925743 0.6186082 0.9464160
 WARNING:
sd(<matrix>) is deprecated.
 Use apply(*, 2, sd) instead.