2012-05-01 35 views
2

假設更有效的方式:從列表中選擇VEC

x = c(1, 2, 3.5, 4, 6, 7.5, 8, 9, 10, 11.5, 12) 
y = c(2.5, 6.5) 
I = split(x, findInterval(x, y)) 
f = function(vec, x) { 
     d = pmax(outer(x, vec, "-"), 0) 
     colSums(d - d^2/2) 
} 

我想計算的f(I[[i]], x)值在每個區間的每一個值,然後找到其I[[i]]實際值有f(I[[i]], x)在每個最大值間隔。 是否有比這更有效的循環任何其他方式:

for (i in 1:length(I)) { 
    max.values[[i]] = I[[i]][which.max(f(I[[i]], x))] 
} 

這是我想要得到的結果是:

> max.values 
[1] 2 6 10 
+0

您的第二段代碼似乎錯誤爲'max.values'不存在。我想你首先需要一個'max.values < - NULL'。 – thelatemail

回答

1

如果你在去除for循環只是感興趣。你可以用一個lapply(。)替換它:

max.values <- unlist(lapply(I, function(v) v[which.max(f(v, x))])); 

這隻會在長度(I)很大時纔會有所作用。 爲了獲得更多的性能,請查看您是否可以簡化f(。)以僅用於查找最大值。 爲了獲得最佳優化,您應該考慮重寫C,C++或Fortran中的性能關鍵部分。

R可能是可怕當數據向量變大,當存在冗長的循環時,或者當可用數據結構不適合任務時,速度變慢。就像一個軼事,我寫了一個「for-loop」無用的R代碼,在Wall time的兩週後(輸入數組:n〜1e6)被殺死。 (R代碼在n〜1e4輸入時運行良好)。 C++等價代碼花了1分鐘。稍微更優化的C++代碼需要10秒...

+0

謝謝你的幫助。 –

0

這是更緊湊,但我不知道它的效率更高......

v <- sapply(lapply(I,f,x=x),which.max) 
mapply(getElement,I,v) 
1

你可以做

mapply('[', I, lapply(lapply(I, f, x), which.max)) 
# 0 1 2 
# 2 6 10 

這裏是中間步驟:

lapply(I, f, x) 
# $`0` 
# [1] -190.875 -142.375 
# 
# $`1` 
# [1] -85.75 -70.75 -26.75 
# 
# $`2` 
# [1] -9.500 -6.125 -1.625 0.375 0.375 0.000 

lapply(lapply(I, f, x), which.max) 
# $`0` 
# [1] 2 
# 
# $`1` 
# [1] 3 
# 
# $`2` 
# [1] 4 
+0

謝謝你的幫助。 –

相關問題