我一直对MARGIN在sweep
和apply
中的两个不同内容的含义感到困惑。考虑:
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看似矛盾的含义?
答案 0 :(得分:4)
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在两种情况下都意味着按行进行操作。
答案 1 :(得分:0)
我觉得我需要加上我的 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 除外)索引)
这很容易记住,因为您实际上不能将负 MARGIN 与 sweep
一起使用!所以如果你忘记了哪个函数需要它们,它会立即提醒你一个错误。
关于不一致:
我相信你是对的 OP,R 核心团队确实在这里做了不一致的功能(因为他们经常这样做)。简单的事实是,apply(A, MARGIN=1, ..., FUN=f)
表示:将 FUN 复制并应用到 A 的每一行,& sweep(A, MARGIN=1, ..., FUN=f)
表示:将 FUN 复制并应用到每个 列 > A.
尽管 LyzandeR 的助记符可能很有用,但我认为他对 row-wise 的定义过于模糊,并且巧妙地改变了它在两个函数中的含义。