2

と仮定する

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ループの他の方法はありますか?

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

これは私が取得したい結果です:

 > max.values
 [1]  2  6 10
4

3 に答える 3

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
于 2012-05-01T03:06:56.957 に答える
1

forループを削除することに興味がある場合。次の方法でlapply(。)に置き換えることができます。

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

これは、length(I)が大きい場合にのみ違いがあります。より多くのパフォーマンスを得るには、最大値を見つけるためだけにf(。)を単純化できるかどうかを確認してください。最適化を最適化するには、パフォーマンスが重要な部分をC、C ++、またはFortranで書き直すことを検討する必要があります。

データベクトルが大きくなる場合、長いループが存在する場合、または使用可能なデータ構造がタスクに適していない場合、Rはひどく遅くなる可能性があります。逸話と同じように、私は「forループ」のないRコードを作成しました。これは、2週間のウォールタイムの後に強制終了されました(入力配列:n〜1e6)。(Rコードは、n〜1e4の入力で正常に実行されます)。C++と同等のコードは1分かかりました。もう少し最適化されたC++コードは10秒かかりました...

于 2012-05-01T03:20:57.747 に答える
0

これはよりコンパクトですが、より効率的かどうかはわかりません...

v <- sapply(lapply(I,f,x=x),which.max)
mapply(getElement,I,v)
于 2012-05-01T03:06:14.590 に答える