了解扫描和应用中的边距的直观方法

An intuitive way to understand MARGIN in sweep and apply

我一直对 MARGIN 在 sweepapply 中似乎意味着 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.

混淆

我正在打印下面的矩阵,以便稍后与 applysweep 进行直观比较:

> 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 都意味着按行操作。

我觉得我需要加 2 美分。首先是我的助记词:

我的助记词: 我将 apply()negative 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 的保存base-1 索引)

这很容易记住,因为您实际上不能在 sweep 中使用负边距!因此,如果您忘记了哪个函数需要它们,它会立即提醒您错误。

关于不一致:

我相信你是对的 OP,R 核心团队确实在这里做出了不一致的功能(他们经常这样做)。简单的事实是,apply(A, MARGIN=1, ..., FUN=f) 意味着:将 FUN 复制并应用到 A 的每个 ,& sweep(A, MARGIN=1, ..., FUN=f) 意味着:将 FUN 复制并应用到每个 [=31= A.

的]列

尽管 LyzandeR 的助记符可能很有用,但我认为他对 row-wise 的定义过于模糊,并且在两个函数之间巧妙地改变了它的含义。