R中的`sweep()函数`以'2L`作为输入

时间:2016-04-08 21:59:31

标签: r function

非常非常具体的问题,但我仍然试图解开R中contr.poly()内的代码。

我认为这是最后的障碍......有一个内部函数make.poly(),它是contr.poly()的关键部分。在make.poly内,我发现生成了raw矩阵,contr.poly(4)为:

     [,1] [,2] [,3] [,4]
[1,]    1 -1.5    1 -0.3
[2,]    1 -0.5   -1  0.9
[3,]    1  0.5   -1 -0.9
[4,]    1  1.5    1  0.3

从那里,函数sweep()将应用以下调用和结果:

Z <- sweep(raw, 2L, apply(raw, 2L, function(x) sqrt(sum(x^2))), 
        "/", check.margin = FALSE)

     [,1]       [,2] [,3]       [,4]
[1,]  0.5 -0.6708204  0.5 -0.2236068
[2,]  0.5 -0.2236068 -0.5  0.6708204
[3,]  0.5  0.2236068 -0.5 -0.6708204
[4,]  0.5  0.6708204  0.5  0.2236068

我熟悉apply函数,我猜sweep类似,至少在语法上是这样,但我不明白2L正在做什么,而我不知道"/"check.margin = F对于理解正在执行的数学运算是否重要。

编辑:非常简单...感谢this - 它只是通过将"/"除以function(x)列应用的矩阵的每个条目来规范化矢量长度。

1 个答案:

答案 0 :(得分:0)

这是一个回答函数sweep()中的操作的例子。

我从矩阵开始

> set.seed(0)
> (mat = matrix(rnorm(30, 5, 3), nrow= 10))
            [,1]     [,2]     [,3]
 [1,]  8.7888629 7.290780 4.327196
 [2,]  4.0212999 2.602972 6.132187
 [3,]  8.9893978 1.557029 5.400009
 [4,]  8.8172880 4.131615 7.412569
 [5,]  6.2439243 4.102355 4.828680
 [6,]  0.3801499 3.765468 6.510824
 [7,]  2.2142989 5.756670 8.257308
 [8,]  4.1158387 2.324237 2.927138
 [9,]  4.9826985 6.307050 1.146202
[10,] 12.2139602 1.287385 5.140179

我希望按列居中数据。当然,我可以使用scale(mat, center = T, scale = F)并完成,但我发现这个函数最后会给你一个属性列表:

attr(,"scaled:center")
[1] 6.076772 3.912556 5.208229

对应于列的意思。很高兴,但我只想要矩阵,干净整洁。事实证明,这可以通过以下方式实现:

> (centered = sweep(mat, 2, apply(mat,2, function(x) mean(x)),"-"))
            [,1]       [,2]        [,3]
 [1,]  2.7120910  3.3782243 -0.88103281
 [2,] -2.0554720 -1.3095838  0.92395779
 [3,]  2.9126259 -2.3555271  0.19177993
 [4,]  2.7405161  0.2190592  2.20433938
 [5,]  0.1671524  0.1897986 -0.37954947
 [6,] -5.6966220 -0.1470886  1.30259477
 [7,] -3.8624730  1.8441143  3.04907894
 [8,] -1.9609332 -1.5883194 -2.28109067
 [9,] -1.0940734  2.3944938 -4.06202721
[10,]  6.1371883 -2.6251713 -0.06805063

因此sweep()函数被理解为:

sweep(here goes matrix name to sweep through, tell me if you want to do it column (2) or row wise (1), but first let's calculate the second argument to use in the sweep - let's use apply on either the same matrix, or another matrix: just type the name here, again... column or row wise, now define a function(x) mean(x), almost done: now the actual operation in the function in quotes: "-" or "/"... and done

有趣的是,我们可以使用完全不同矩阵的列的平均值来扫描原始矩阵 - 可能是更复杂的操作,更符合开发此函数的原因。

> aux.mat = matrix(rnorm(9), nrow = 3)
> aux.mat
           [,1]       [,2]      [,3]
[1,] -0.2793463 -0.4527840 -1.065591
[2,]  1.7579031 -0.8320433 -1.563782
[3,]  0.5607461 -1.1665705  1.156537

> (centered = sweep(mat, 2, apply(aux.mat,2, function(x) mean(x)),"-"))
            [,1]     [,2]     [,3]
 [1,]  8.1090952 8.107913 4.818142
 [2,]  3.3415323 3.420105 6.623132
 [3,]  8.3096302 2.374162 5.890954
 [4,]  8.1375203 4.948748 7.903514
 [5,]  5.5641567 4.919487 5.319625
 [6,] -0.2996178 4.582600 7.001769
 [7,]  1.5345313 6.573803 8.748253
 [8,]  3.4360710 3.141369 3.418084
 [9,]  4.3029308 7.124183 1.637147
[10,] 11.5341925 2.104517 5.631124
相关问题