我一直对 MARGIN 在
sweep
和 apply
中似乎意味着 2 个不同的事物感到困惑。考虑:
m <- matrix(1:6, ncol = 2)
# The "- 1" operation is applied to all cells in each row
sweep(m, MARGIN = 1, 1, "-")
# The sum operation is applied to each column
apply(m, MARGIN = 1, sum)
你有助记符来理解 MARGIN 这个看似矛盾的含义吗?
MARGIN 参数在两个函数中的含义完全相同,即按行操作。过去我曾多次对
sweep
感到困惑,但我认为您对 apply
感到困惑。
我正在打印下面的矩阵,以便稍后可以轻松地与
apply
和 sweep
进行视觉比较:
> m
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
首先,当 MARGIN 为 1 时,
sweep
函数会执行按行操作。我将稍微更改第三个参数,以便更加明显:
> sweep(m, MARGIN = 1, 1:3, "-")
[,1] [,2]
[1,] 0 3
[2,] 0 3
[3,] 0 3
在上述情况下,数字 1 从第 1 行中扣除,数字 2 从第 2 行中扣除,数字 3 从第 3 行中扣除。因此,显然这是一个逐行操作。
现在让我们看看下面的
apply
函数:
> apply(m, MARGIN = 1, sum)
[1] 5 7 9
显然,矩阵有 3 行 2 列。很容易暗示这也是一个逐行操作,因为我们有 3 个结果,即与行数相同。如果我们检查数字也可以证实这一点。第 1 行总计为 5,第 2 行总计为 7,第 3 行总计为 9。
因此,显然,两种情况下的 MARGIN 都意味着按行操作。
关于不一致:
首先OP你是对的,他们确实不一致!
这是不一致的具体证明/示例:
您知道 apply 和 swing 可以用来做同样的事情吗? 那么,当你这样做时会发生以下情况:
(A = matrix(1:9, 3))
(B=sweep(A, MARGIN=1, 1:3, FUN='-'))
(C=apply(A, MARGIN=2, 1:3, FUN='-'))
stopifnot(all(B==C))
# ^ No error they are equal! but MARGINS are opposite!!
明确的输出是:
> (A = matrix(1:9, 3))
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> (B=sweep(A, MARGIN=1, 1:3, FUN='-'))
[,1] [,2] [,3]
[1,] 0 3 6
[2,] 0 3 6
[3,] 0 3 6
> (C=apply(A, MARGIN=2, 1:3, FUN='-'))
[,1] [,2] [,3]
[1,] 0 3 6
[2,] 0 3 6
[3,] 0 3 6
简单的事实是,
apply(A, MARGIN=1, ..., FUN=f)
表示:复制并应用FUN到A的每个行,sweep(A, MARGIN=1, ..., FUN=f)
表示:复制并应用FUN到A的每个列。
我的助记词: 我将
apply()
与 负 MARGINs 一起使用(即 apply(A, MARGIN=2, ...)
变为 --> apply(A, MARGIN=-1, ...)
),这使得行为与扫描一致(就绝对值而言),并且具有使 MARGIN 参数一致的额外好处使用 numpy/torch/matlab 轴参数!!例如, torch.mean(arr, axis=0)
== np.mean(arr, axis=0)
== apply(arr, MARGIN=-1, mean)
(当然保存 R 的基数 1 索引)
这很容易记住,因为你实际上不能将负MARGIN与
sweep()
一起使用!因此,如果您忘记哪个函数需要它们,它会立即提醒您错误。 ...负数也排在正数之前,就像字母表中 (A)apply 排在 (S)weep 之前一样。