2017-02-19 6 views
1

大きなマルチバンドラスタで計算を実行し、RasterBrickをエクスポートする必要があります。メモリの目的で、ラスタパッケージのcalc()関数を使用します効率。関数は、自分自身で細かい動作しますが、私はcalc()に含めるしようとすると、私はこのエラーを取得しておいてください。calc()関数を使用しているエラー:この関数を使用できません。

Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) : cannot use this function

どのように私はこの作業を行うことができますか?

簡体コード:

fn = system.file("external/test.grd", package="raster") 
s = stack(fn, fn, fn, fn) 

out = calc(s, fun = function(x){ 
    for (i in 1:nlayers(x)){ 
    x[[i]] = x[[i]] - cellStats(x[[i]], "min") 
    x[[i]] = x[[i]]* 5 
    } 
    list = unstack(x) 
    out = brick(list) 
    return(out) 
} 
) 

Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) : 
    cannot use this function 

答えて

1

calcヘルプから:

For large objects calc will compute values chunk by chunk. This means that for the result of fun to be correct it should not depend on having access to all values at once. For example, to scale the values of a Raster* object by subtracting its mean value (for each layer), you would not do, for Raster object x:

calc(x, function(x)scale(x, scale=FALSE))

Because the mean value of each chunk will likely be different. Rather do something like

m <- cellStats(x, 'mean')

x - m

ので、あなたの関数は、それが働いた場合でも、おそらくあなたに誤った結果を与えるだろう。私はしかし、なぜ機能がうまくいかないのかは完全にはわかりません:おそらくの使用を避けるためにcalcに内部チェックがあるかもしれません。

は "あなた" の計算を行うには、しかし、あなたは単に使用できます。

out = s 
for (i in 1:nlayers(s)) { 

    out [[i]] = (s [[i]] - cellStats(s[[i]], 'min', na.rm = T))*5 

} 
+1

感謝を! forループのために関数が機能していなかったことが分かります。 「calc」はバンドとインデックスを区別します。あなたの解決策は私が以前に持っていたものですが、より効率的なメモリがあるので 'calc'が必要です。 'cellStats'に関しては、NA値を持つ薄いものが本当に問題でした。 – Danple

+0

あなたはそれを解決してうれしいです。ただし、ヘルプの警告を覚えておいてください:各レイヤーから平均を引いて、 'calc'がチャンクで機能する場合は、間違った出力(つまり、最初のグループに減算する値行の数は最後から減算する行とは異なります)。 – lbusett

関連する問題