R栅格 - 创建包含循环遍历多个图层的条件的图层

时间:2017-12-12 08:26:02

标签: r loops layer raster

我正在使用时间序列栅格砖。砖块有365层,代表一年中每一天的价值。

我想创建一个新图层,其中每个单元格保存满足特定条件的一年中的日期。

我目前的方法是以下(APHRO是光栅砖),但返回以下错误信息:

enter code here
r <- raster(ncol=40, nrow=20)
r[] <- rnorm(n=ncell(r))
APHRO <- brick(x=c(r, r*2, r))    
NewLayer <- calc(APHRO, fun=FindOnsetDate(APHRO))

返回此错误:

 Error in .local(x, ...) : not a valid subset 

正在解析的函数:

FindOnsetDate <- function (s) {
  x=0  
  repeat {
    x+1
    if(s[[x]] >= 20 | s[[x]] + s[[x+1]] >= 20 & ChkFalseOnset() == FALSE)
    {break}
  }
  return(x);
}

第三个条件的功能是:

ChkFalseOnset <- function (x) {



  for (i in 0:13){

    if (sum(APHRO[[x+i:x+i+7]]) >= 5)
    {return(FALSE); break}
    return(TRUE)  
  }
}

提前谢谢!!!!

如果我应该提供更多信息,请告诉我 - 试着保持简约。

2 个答案:

答案 0 :(得分:0)

我建议一个基本的两步过程。以365天为例:

set.seed(123)

r <- raster(ncol=40, nrow=20)

r_list <- list()

for(i in 1:365){
  r_list[[i]] <- setValues(r,rnorm(n=ncell(r),mean = 10,sd = 5))
}

APHRO <- brick(r_list)

对每次迭代使用基本逻辑测试:

r_list2 <- list()

for(i in 1:365){
  if(i != 365){
    r_list2[[i]] <- APHRO[[i]] >= 20 | APHRO[[i]] + APHRO[[i+1]] >= 20
  }else{
    r_list2[[i]] <- APHRO[[i]] >= 20
  }
}

按年计算总和:

NewLayer <- calc(brick(r_list2), fun=sum)

plot(NewLayer)

enter image description here

答案 1 :(得分:0)

问题是你的功能不好:

import numpy as np
import itertools
import math

N_CHUNKS = 3

def improved_solve(LH, errtype='relerr'):
    N = math.factorial(7)
    # accept anything that looks like a 2d array
    LH = np.asanyarray(LH)
    # build equidistant columns
    C = np.array([np.linspace(l, h, 7) for l, h in LH])
    # subtract offset; it's cheaper now than later
    c0, c1, c2, c3 = C - 25
    # list all permutiations of a single column
    p = np.array(list(itertools.permutations(range(7))))
    # split into left and right halves, compute all relative permutiations
    # and sort them by their sums of corresponding elements.
    # Left pairs in ascending, right pairs in descending order.
    L = np.sort(c0 + c1[p], axis=1)
    R = np.sort(c2 + c3[p], axis=1)[:, ::-1]
    # For each pair of permutations l in L, r in R compute the smallest
    # possible error (sum of squared deviations.)
    if errtype == 'relerr':
        err = np.empty((N, N))
        split = np.linspace(0, N, N_CHUNKS+1, dtype=int)[1:-1]
        for LCH, ECH in zip(np.split(L, split, axis=0),
                            np.split(err, split, axis=0)):
            dev = LCH[:, None] + R[None, :]
            ((dev / (100+dev))**2).sum(axis=-1, out=ECH)
        del dev
    elif errtype == 'abserr':
        err = (np.add.outer(np.einsum('ij,ij->i', L, L),
                            np.einsum('ij,ij->i', R, R))
               + np.einsum('ik, jk->ij', 2*L, R))
    else:
        raise ValueError
    # find pair of pairs with smallest error
    i = np.argmin(err.ravel())
    i1, i3 = np.unravel_index(i, (N, N))
    # recreate shuffled table
    c0, c1, c2, c3 = C        
    lidx = np.argsort(c0 + c1[p[i1]])
    ridx = np.argsort(c2 + c3[p[i3]])[::-1]
    C = np.array([c0[lidx], c1[p[i1]][lidx], c2[ridx], c3[p[i3]][ridx]])
    # correct rowsums, calculate error and corrcoef and return
    if errtype == 'relerr':
        result = C * (100.0 / C.sum(axis=0, keepdims=True))
        err = math.sqrt((((result-C)/C)**2).mean())
    else:
        result = C + (25 - C.mean(axis=0, keepdims=True))
        err = math.sqrt(((result-C)**2).mean())
    rs = np.sort(result, axis=1)
    cc = tuple(np.corrcoef(ri, range(7))[0, 1] for ri in rs)
    return dict(table=result.T, avgerr=err, corrcoefs=cc)

def solve(LH, errtype='relerr'):
    LH = np.asanyarray(LH)
    if errtype=='relerr':
        err1 = 200 / LH.sum()
        diff = np.diff(LH * err1, axis=1).ravel()
    elif errtype=='abserr':
        err1 = 25 - LH.mean()
        diff = np.diff(LH, axis=1).ravel()
    else:
        raise ValueError
    C = np.array([np.linspace(-d/2, d/2, 7) for d in diff])
    c0, c1, c2, c3 = C
    p = np.array(list(itertools.permutations(range(7))))
    L = np.sort(c0 + c1[p], axis=1)
    R = np.sort(c2 + c3[p], axis=1)[:, ::-1]
    err = (np.add.outer(np.einsum('ij,ij->i', L, L),
                        np.einsum('ij,ij->i', R, R))
           + np.einsum('ik, jk->ij', 2*L, R)).ravel()
    i = np.argmin(err)
    i1, i3 = np.unravel_index(i, (math.factorial(7), math.factorial(7)))
    L = np.argsort(c0 + c1[p[i1]])
    R = np.argsort(c2 + c3[p[i3]])[::-1]
    ref = [np.linspace(l, h, 7) for l, h in LH]
    if errtype=='relerr':
        c0, c1, c2, c3 = [np.linspace(l, h, 7) for l, h in LH * err1]
        C = np.array([c0[L], c1[p[i1]][L], c2[R], c3[p[i3]][R]])
        err2 = 100 / np.sum(C, axis=0)
        C *= err2
        cs = list(map(sorted, C))
        err = math.sqrt(sum((c/r-1)**2 for ci, ri in zip(cs, ref) for c, r in zip(ci, ri)) / 28)
    elif errtype=='abserr':
        c0, c1, c2, c3 = [np.linspace(l, h, 7) for l, h in LH + err1]
        C = np.array([c0[L], c1[p[i1]][L], c2[R], c3[p[i3]][R]])
        err2 = 25 - np.mean(C, axis=0)
        C += err2
        cs = list(map(sorted, C))
        err = math.sqrt(sum((c-r)**2 for ci, ri in zip(cs, ref) for c, r in zip(ci, ri)) / 28)
    else:
        raise ValueError
    cc = tuple(np.corrcoef(ci, range(7))[0, 1] for ci in cs)
    return dict(table=C.T, avgerr=err, corrcoefs=cc)

for problem in [((75, 98), (6, 15), (2, 8), (0.05, 0.5)),
                ((11, 41), (4, 34), (37, 49), (0.01, 23.99)),
                ((80, 94), (5, 14), (0.5, 5), (0.05, 0.5)),
                ((36.787862883725872, 43.967159949544317),
                 (40.522239654303483, 47.625869880574164),
                 (19.760537036548321, 49.183056694462799),
                 (45.701873101046154, 48.051424087501672))]:
    for errtype in ('relerr', 'abserr'):
        print()
        columns = []
        for solver in (solve, improved_solve):
            sol = solver(problem, errtype)
            column = [[' '.join((solver.__name__, errtype))]] + \
                     [[k + ':'] + [' '.join([f'{e:8.5f}' for e in r])
                                   for r in np.atleast_2d(v)]
                      for k, v in sol.items()]
            column = (line for block in column for line in block)
            columns.append(column)
        for l, r in zip(*columns):
            print(f"{l:39s} {r:39s}")

problems = []
for i in range(0):
    problem = np.sort(np.random.random((4, 2)), axis=1) * 50
    for errtype in ('relerr', 'abserr'):
        sol0 = solve(problem, errtype)
        sol1 = improved_solve(problem, errtype)
        if not np.allclose(sol0['table'], sol1['table']):
            print(i, end= " ")
            if np.abs((sol0['avgerr']-sol1['avgerr'])
                      /(sol0['avgerr']+sol1['avgerr']))>1e-6:
                print(problem)
                problems.append(problem)
                columns = []
                for sol, name in [(sol0, 'old '), (sol1, 'improved ')]:
                    column = [[name + errtype]] + \
                             [[k + ':'] + [' '.join([f'{e:8.5f}' for e in r])
                                           for r in np.atleast_2d(v)]
                              for k, v in sol.items()]
                    column = (line for block in column for line in block)
                    columns.append(column)
                for l, r in zip(*columns):
                    print(f"{l:39s} {r:39s}")

也许是这样的:

FindOnsetDate <- function (s) {
   x=0  
   repeat {
     x+1
     if(s[[x]] >= 20 | s[[x]] + s[[x+1]] >= 20)
     {break}
   }
   return(x);
 }
 FindOnsetDate(1:100)
 #Error in s[[x]] : 
 # attempt to select less than one element in get1index <real>

现在可以使用:

FindOnsetDate <- function (s) {
   j <- s + c(s[-1], 0)
   sum(j > 20 | s > 20)
   # if all values are positive, just do sum(j > 20)
}
FindOnsetDate(1:20)
#10