R中apply函数中的边距参数

Posted

技术标签:

【中文标题】R中apply函数中的边距参数【英文标题】:Margin argument within the apply function in R 【发布时间】:2015-09-21 20:22:47 【问题描述】:

这个问题更多的是关于 apply 函数中的 MARGIN 参数。假设我想将下面的矩阵乘以下面的向量,这样我就可以将第一个矩阵元素乘以第一个向量元素,然后再乘以第二个,以此类推。我使用以下代码:

matrix <- matrix(1:10)
vector <- c(10:19)
t(apply(matrix,2,'*',vector))

返回一个非常干净的结果:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]   10   22   36   52   70   90  112  136  162   190

但是如果我改变 MARGIN = 2,我会得到这个结果:

matrix <- matrix(1:10)
vector <- c(10:19)
t(apply(matrix,1,'*',vector))

       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]   10   11   12   13   14   15   16   17   18    19
 [2,]   20   22   24   26   28   30   32   34   36    38
 [3,]   30   33   36   39   42   45   48   51   54    57
 [4,]   40   44   48   52   56   60   64   68   72    76
 [5,]   50   55   60   65   70   75   80   85   90    95
 [6,]   60   66   72   78   84   90   96  102  108   114
 [7,]   70   77   84   91   98  105  112  119  126   133
 [8,]   80   88   96  104  112  120  128  136  144   152
 [9,]   90   99  108  117  126  135  144  153  162   171
[10,]  100  110  120  130  140  150  160  170  180   190

我假设如果 MARGIN = 1,第一个矩阵行将乘以每个向量元素,然后是第二个矩阵行,等等,而 MARGIN = 2 只是将第一个矩阵行乘以第一个向量元素?

谁能给我解释一下具体有什么区别?

【问题讨论】:

首先:为什么是apply?由于矢量化,您只需 t(matrix * vector) 即可实现相同目的。 没有真正的理由,我只是不确定我还能怎么问这个问题。我想我可以问“MARGIN = 1 和 2 有什么区别,但我总是喜欢例子。 我已经发布了一个解决方案,希望它清楚。 【参考方案1】:

apply 函数的边距可以用维度来解释:1 = 行,2 = 列。

当您设置MARGIN = 1 时,您是在告诉R 将矩阵的每一行与名为vector 的向量相乘。因为矢量化,即使你的原始结果是一行只有一个元素,你也会得到 10 个元素。

其中的原因是,借用 Norman Matloff 在优秀著作《R 编程的艺术》中的话:

当对两个向量应用运算时,要求它们是 长度相同,R自动循环,或者重复,较短的那个, 直到它足够长以匹配更长的那个

几天前有一个关于矢量化和==函数行为的非常相似的讨论,你可以找到它here。

回到你的问题,让我们不考虑整个 apply 函数,而只考虑它的一次迭代,比如矩阵的第一个元素乘以向量。我们有:

 matrix[1]
[1] 1
 vector
 [1] 10 11 12 13 14 15 16 17 18 19
 matrix[1] * vector
 [1] 10 11 12 13 14 15 16 17 18 19

正如我引用的书中所述,R 采用较短的向量(在本例中为 matrix[1])并与 vector 相乘,但由于 vector 较长,R 采用较短的向量并将其回收为“n”时间越长越快,在本例中为 10 次。

当然,我们只是在一种情况下。 apply 函数对每一行执行此步骤,共十行。结果,我们得到了一个 10 x 10 的矩阵。

【讨论】:

啊啊啊啊,我明白了!谢谢! 不客气,如果您发现它对您的目的有用且详尽,请不要忘记接受答案。 我将这里的matrix[1] 替换为matrix[1, ],因为apply 是按行而不是按元素进行子集化。 @NickK 对不起,我不明白你在说什么。我的只是一个例子,我只想将矩阵的一个元素与向量相乘,这就是为什么我说“让我们考虑不是整个应用函数,而只是一次迭代” @SabDeM 我明白你的意思,但是当apply 与边距1 一起使用时,它会遍历行(例如matrix[1, ]matrix[2, ])而不是矩阵的元素.对于 OP 的示例,它没有区别,但它会处理具有多于一列的矩阵。

以上是关于R中apply函数中的边距参数的主要内容,如果未能解决你的问题,请参考以下文章

TextBlock 中的边距文本

如何使浮动元素的边距折叠

markdown 盒模型中的边距和填充属性

iOS 中 UI 元素的边距和内边距

Safari 中的边距顶部与 chrome 不同

matlab subplot 的边距(with tight margins)