[英]What are the Implications for my Output of a "Stack Imbalance" Warning when Using a For Loop?
我做了一個 function 來計算 R 圖形上隨機生成的 (x,y) 點的人口加權平均密度 (PWAD) 。 function 並不完美......我不是根據它們所在的網格正方形而是根據它們最接近的網格中心將點分配給網格正方形,然后我假設中心拉出的區域是大小網格(1 或 0.25)。 function 的目的是測試在不同“總人口”下對網格位置和大小的敏感性。 這是 function(評論是為我的未來版本寫的):
pwad.grid <- function(xval, yval, totalpop) {
values <- data.frame(xval, yval)
# I'll use the four grids that I've already got
# the original size grids
# I'm not cleaning up this code, i.e. it's as it was originally developed for a
# non-function use when I only wanted to do this once
# again, I'm using minimum Euclidean distance of (x, y) point to grid centre to
# fudge assignation to grids
lowbounds3 <- 0.25
highbounds3 <- 10.25
centres1 <- data.frame(x=seq(0.05, 1, .1) * 10, y=10 *
as.vector(matrix(rep(seq(0.05, 1, .1), each=10),
nrow=10)))
centres2 <- data.frame(x=seq(0, 10, 1), y=10 *
as.vector(matrix(rep(seq(0, 1, .1), each=11),
nrow=11)))
centres3 <- data.frame(x=seq(lowbounds3, highbounds3, 1), y=
as.vector(matrix(rep(seq(lowbounds3, highbounds3, 1),
each=11), nrow=11)))
#the quarter size integer aligned grid
lowbounds4 <- 0.25
highbounds4 <- 9.75
centres4 <- data.frame(x=seq(lowbounds4, highbounds4, .5), y=
as.vector(matrix(rep(seq(lowbounds4, highbounds4, .5),
each=20), nrow=20)))
# and now the stores, which I alter somewhat to allow for varying populations
# reminder: these are the calculations for the Euclidean distances
# the code inside the matrix calculates the distances on a repeated entry basis
# i.e. when there are 100 centres, each (x, y) is repeated 100 times, once for
# each centre #the matrix then arranges the results so that each (x, y) occupies
# only one row once again
stores1 <- matrix(sqrt(rowSums((values[rep(1:totalpop, each=100), ] -
centres1[rep(1:100, totalpop), ])^2)),
ncol=100, byrow=TRUE)
stores2 <- matrix(sqrt(rowSums((values[rep(1:totalpop, each=121), ] -
centres2[rep(1:121, totalpop), ])^2)),
ncol=121, byrow=TRUE)
stores3 <- matrix(sqrt(rowSums((values[rep(1:totalpop, each=121), ] -
centres3[rep(1:121, totalpop), ])^2)),
ncol=121, byrow=TRUE)
stores4 <- matrix(sqrt(rowSums((values[rep(1:totalpop, each=400), ] -
centres4[rep(1:400, totalpop), ])^2)),
ncol=400, byrow=TRUE)
# assigning points to groups based on the minimum Euclidean Distance
groups1 <- max.col(-stores1)
groups2 <- max.col(-stores2)
groups3 <- max.col(-stores3)
groups4 <- max.col(-stores4)
# calculating the PWADs
pwad1 <- sum(table(groups1) * table(groups1)/totalpop)
pwad2 <- sum(table(groups2) * table(groups2)/totalpop)
pwad3 <- sum(table(groups3) * table(groups3)/totalpop)
mill <- table(groups4) / 0.25
pwad4 <- sum(mill * table(groups4)/totalpop)
# outputs grouped together
data.frame(pwad1, pwad2, pwad3, pwad4)
}
為了查看不同人口規模的影響,我一直在 R 中使用 for 循環。 每個循環是 1000 次迭代並生成四組 1000 個 PWAD(每個網格類型一個)。 對於大於 100 的人口,循環需要一分鍾以上才能在我的機器上完成。 對於 1000 人來說,大約需要 12-13 分鍾。 根據我已經完成的各種人口,我預計 5000 人口需要大約 66 分鍾。 那是一個時代,但我要出去了,為什么不跑呢?
這是我為 5000 人運行的循環和前面的代碼:
# I created sims earlier when I ran my very first population.
sims <- data.frame(baseline=1:1000, ptfive=1:1000, pt75=1:1000, qtrsize=1:1000)
# I did not run it again when I ran the below:
xvalues <- matrix(runif(5000 * 1000) * 10, ncol=1000)
yvalues <- matrix(runif(5000 * 1000) * 10, ncol=1000)
dim(xvalues)
start_time <- Sys.time()
for (i in 1:1000) {
xval <- xvalues[, i]
yval <- yvalues[, i]
sims[i, ] <- pwad.grid(xval, yval, 5000)
#commented out just in case I forget and run all chunks
}
end_time <- Sys.time()
#started at 5:51, expect to finish approx 6:51-
#write.csv(sims, "5000sim.csv")
end_time - start_time
這是控制台 output 運行(除了模擬人生)生成:
xvalues <- matrix(runif(5000 * 1000) * 10, ncol=1000)
yvalues <- matrix(runif(5000 * 1000) * 10, ncol=1000)
dim(xvalues)
# [1] 5000 1000
start_time <- Sys.time()
for (i in 1:1000) {
xval <- xvalues[, i]
yval <- yvalues[, i]
sims[i, ] <- pwad.grid(xval, yval, 5000)
#commented out just in case I forget and run all chunks
}
# Warning: stack imbalance in 'for', 2 then -1
end_time <- Sys.time()
end_time - start_time
# Time difference of 1.251416 hours
如您所見,不幸的是,我收到了警告(不是錯誤。)。 因為我一直將輸出保存為 csv 文件。 我沒有使用 set.seed() 所以這是我使用的特定數字集導致了警告......
我的問題是:
在搜索 Google 時,我看到的主要是 Rcpp 或不同語言上下文中“堆棧不平衡”的描述。 如您所見,我僅使用基本 R 函數來構建我的 function 和一個 for 循環,它也來自基本 R。
如果它是 memory 東西:
但那是后循環。 我不知道它在運行之前或運行期間是什么。
不確定標簽,如果需要更多詳細信息,請告訴我。 非常感謝!
SLR的完成預測:
cloudnumber <- c(10, 100, 250, 500, 500, 750, 900, 1000, 1250)
yseconds <- c(9.173949, 55.87789, 2.186122 * 60, 4.707054 * 60, 4.606928 * 60,
7.831578 * 60, 9.376838 * 60, 12.30255 * 60, 15.15093 * 60)
runtime <- lm(yseconds ~ cloudnumber)
predict(runtime, data.frame(cloudnumber=newdata, type="response")) / 60
添加 5000 人口的長度會將預測的 10000 人口從 120.62128 分鍾調整為 150.58184 分鍾。
“警告:'for' 中的堆棧不平衡,2 然后 -1”消息表示 C/C++ 級別代碼中的某些內容未正確編程。 當 C 級別代碼創建 R 變量時,需要對其調用PROTECT
,這樣垃圾收集器就不會釋放它。 在調用結束時,它應該進行匹配的UNPROTECT
調用,以便可以釋放 object。
R 在外部調用的開始和結束時檢查這些,並在結果不平衡時發出警告。
現在,如果您向我們展示的所有代碼都在運行,這表明 R 中存在內部錯誤。 不幸的是,由於未調用set.seed
,您的示例無法重現,而且運行時間很長:其他任何人都很難重現它。
你問這是否會影響你的結果。 我會說它可以,但我當然不知道它確實如此。
對於您的下一次運行,您絕對應該在開始時使用set.seed(n)
將 RNG 值固定為已知n
。 如果警告至少再次發生,那么您可以嘗試相同的運行並查看它是否可重現。 希望它會,然后你可以嘗試調試它:它是否發生在較短的 for 循環中? 如果您運行options(warn=2)
將警告轉換為錯誤,則可以將其范圍縮小到導致問題的確切步驟。 讓我們(或 R 開發人員)知道您是否獲得了可重現的東西,也許該錯誤可以修復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.