2017-02-19 1 views
1

J'ai besoin d'exécuter des calculs sur de grands rasters multi-bandes et d'exporter un RasterBrick, et j'essaie de le faire en utilisant la fonction calc() dans le paquetage raster, à des fins de mémoire Efficacité. La fonction fonctionne très bien lui-même, mais lorsque je tente de l'inclure dans calc(), je continue à obtenir cette erreur:Erreur lors de l'utilisation de la fonction calc(): impossible d'utiliser cette fonction

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

Comment puis-je faire ce travail?

Code simplifié:

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 

Répondre

1

De calc aide:

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

donc, votre fonction, même si cela a fonctionné, vous donnerait probablement des résultats incorrects. Je ne suis pas entièrement sûr pourquoi la fonction ne fonctionne pas, cependant: peut-être il y a un contrôle interne dans calc pour éviter l'utilisation de cellStats.

Pour faire "votre" calcul, cependant, vous pouvez utiliser simplement:

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

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

} 
+1

Merci! Il s'avère que la fonction ne fonctionnait pas à cause de la boucle for. Il s'avère que 'calc' distingue les bandes et les indices par lui-même. Votre solution est ce que j'avais avant, mais j'ai besoin de 'calc' parce que c'est plus efficace en mémoire. En ce qui concerne 'cellStats', j'aurais du mal à avoir des valeurs NA. – Danple

+0

heureux que vous l'avez résolu. Cependant, gardez à l'esprit l'avertissement dans l'aide: si vous essayez de soustraire la moyenne de chaque couche et que 'calc' fonctionne en morceaux, vous aurez de mauvaises sorties (c'est-à-dire la valeur que vous soustrayez au premier groupe des lignes sera différent de celui que vous soustrayez du dernier). – lbusett