apply() 与 swing()

问题描述 投票:0回答:2

我正在写笔记来比较 apply() 和 swing() 并发现以下奇怪的差异。为了生成相同的结果,sweep() 需要 MARGIN = 1,而 apply 需要 MARGIN = 2。此外,指定矩阵的参数在 apply() 中为大写 X,但在 swing() 中为小写。

my.matrix <- matrix(seq(1,9,1), nrow=3)
row.sums <- rowSums(my.matrix)
apply.matrix <- apply(X = my.matrix, MARGIN = 2, FUN = function (x) x/row.sums)
sweep.matrix <- sweep(x = my.matrix, MARGIN = 1, STATS = rowSums(my.matrix), FUN="/")
apply.matrix - sweep.matrix ##yup same matrix

sweep()不是一个“应用类型”函数吗?这只是 R 的另一个怪癖还是我失去了理智?

r row apply
2个回答
5
投票

请注意,对于

apply

如果每次调用“FUN”都返回一个长度为“n”的向量,那么“apply”将返回一个维度为“c(n, dim(X)[MARGIN])”的数组(如果“n > 1”)

在您的示例中,在两种情况下都可以(并且应该)将

MARGIN
设置为
1
;但
apply
的返回值应该被转置。 这是最容易看出原始矩阵是否不是方阵的方法:

my.matrix <- matrix(seq(1,12,1), nrow=4)
apply.matrix <- t(apply(X = my.matrix, MARGIN = 1, FUN = function(x) x/sum(x)))
sweep.matrix <- sweep(x = my.matrix, MARGIN = 1, STATS = rowSums(my.matrix), FUN="/")
all.equal(apply.matrix, sweep.matrix)
# [1] TRUE

另请参阅 Can you Implement 'sweep' using apply in R? 的答案,它说的是非常相同的事情。


0
投票

我不同意黄伟煌的观点。

我们用一个更简单的例子来说明一下, (按照他的建议使用非方阵):

(A = matrix(1:12, 3)) # Non-Square Matrix
(B=sweep(A, MARGIN=1, 1:3, FUN='/')) # only difference is margin
(C=apply(A, MARGIN=2, 1:3, FUN='/')) # only difference is margin
stopifnot(all.equal(B, C)) # they're equal but margins are opposite

如果您要尝试他建议的转置:

stopifnot(all.equal(B, t(C))) # not equal, transposing doesn't work

我在这里说的基本上是同样的事情:理解扫描和应用中的MARGIN的直观方法

附注需要记住的一个好记法是,您可以使用负边距进行应用(例如 MARGIN=-1),以获得与扫描中正 MARGIN 相同的行为。

© www.soinside.com 2019 - 2024. All rights reserved.