使用apply函数嵌套for循环

时间:2017-08-19 15:57:39

标签: r

我想知道是否有办法使用apply函数执行以下矩阵填充?我已经读过,apply比循环更有效。出于某种原因,我在使用apply函数系列时遇到了困难。

我希望填充一个矩阵。我使用数据框中的数据作为数据填充的条件。

以下是数据逻辑的示例;它是简化的,但它涵盖了基于规则的人口的基本要素。

<?php
include('../../Connections/koneksi.php');

// reading json file
$array = json_decode( $_POST['table-bordered'] );
print_r ($array);


?>

1 个答案:

答案 0 :(得分:3)

apply并不比for循环更有效,因此如果您正在寻找效率,那么这不是一个好方法。相反,您应该使用矢量化操作。让我们分开你的for循环:

首先,如果元素位于对角线上,则元素取值为1,这可以通过diag函数实现:

diag(n)
#      [,1] [,2] [,3] [,4]
# [1,]    1    0    0    0
# [2,]    0    1    0    0
# [3,]    0    0    1    0
# [4,]    0    0    0    1

如果sample_data的第二列中的条目i和j不匹配,并且sample_data的第三列中的条目i和j,则非对角条目(i,j)取值0.5 1}}匹配。这可以通过矢量化outer函数来实现:

topn.2 <- head(sample_data[,2], n)
topn.3 <- head(sample_data[,3], n)
0.5 * (outer(topn.2, topn.2, "!=") & outer(topn.3, topn.3, "=="))
#      [,1] [,2] [,3] [,4]
# [1,]    0  0.0  0.0    0
# [2,]    0  0.0  0.5    0
# [3,]    0  0.5  0.0    0
# [4,]    0  0.0  0.0    0

如果条目i和j在第2列和第3列中匹配,或者两者都不匹配,则非对角线条目(i,j)取值0.25。同样,这可以通过outer

来实现
0.25 * (outer(1:n, 1:n, "!=") & (outer(topn.2, topn.2, "==") + outer(topn.3, topn.3, "==")) != 1)
#      [,1] [,2] [,3] [,4]
# [1,] 0.00 0.00 0.25 0.25
# [2,] 0.00 0.00 0.00 0.25
# [3,] 0.25 0.00 0.00 0.00
# [4,] 0.25 0.25 0.00 0.00

将所有内容添加到一起会产生for循环的完全矢量化替换:

diag(n) +
  0.5 * (outer(topn.2, topn.2, "!=") & outer(topn.3, topn.3, "==")) +
  0.25 * (outer(1:n, 1:n, "!=") & (outer(topn.2, topn.2, "==") + outer(topn.3, topn.3, "==")) != 1)
#      [,1] [,2] [,3] [,4]
# [1,] 1.00 0.00 0.25 0.25
# [2,] 0.00 1.00 0.50 0.25
# [3,] 0.25 0.50 1.00 0.00
# [4,] 0.25 0.25 0.00 1.00