[英]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.