簡體   English   中英

使用apply函數嵌套for循環

[英]Nested for loop using apply function

我想知道是否有一種方法可以使用apply函數進行下面的矩陣填充? 我讀過,apply比for循環更有效。 由於某種原因,我在應用功能家族中苦苦掙扎。

我正在尋找一個矩陣。 我正在使用數據框中的數據作為數據填充的條件。

以下是數據邏輯的示例; 它經過簡化,但涵蓋了基於規則的總體要素。

id_1 <- c(1, 1, 1, 1, 1, 1)
id_2 <- c(1, 1, 2, 2, 3, 3)
id_3 <- c(1, 2, 2, 3, 3, 4)
amt <- c(10, 15, 20, 25, 30, 35)

sample_data <- data.frame(id_1, id_2, id_3, amt)

n <- length(sample_data)

cor <- matrix(ncol = n, nrow = n)

i <- 1
j <- 1

for (i in 1:n) {
  for (j in 1:n) {
    if (i == j) {
      cor[i,j] = 1
    } else if (sample_data[2][i,] == sample_data[2][j,] & sample_data[3][i,] != sample_data[3][j,]) {
      cor[i,j] = 0
    } else if (sample_data[2][i,] != sample_data[2][j,] & sample_data[3][i,] == sample_data[3][j,]) {
      cor[i,j] = 0.5
    } else {
      cor[i,j] = 0.25
    }
  }
}

cor

     [,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

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。 這可以通過向量化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列中均匹配,或者在第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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM