for循环输出的列表返回空

时间:2018-09-17 15:44:27

标签: r for-loop crosstab r-raster

我编写了代码,以获取覆盖栅格的不同区域(由shapefile分隔)的栅格堆栈的交叉表结果。但是,我得到的是一个空列表。

这是功能:

transitions <- function(bound, themat) {    # bound = shapefile # themat = rasterstack
    result = vector("list", nrow(bound))    # empty result list
    names(result) = bound@data$GEOCODIGO

    for (i in 1:nrow(bound)) {    # this is the number of polygons to iterate through
        single <- bound[i,]    # selects a single polygon
        clip <- mask(crop(themat, single), single)    # crops the raster to the polygon boundary

        result[i] <- crosstab(clip, digits = 0, long = FALSE, useNA = FALSE)
        return(result)
    }
}

我已经测试了shapefile中第一个对象的步骤,该对象位于for循环之外;而且效果很好。但是我仍然不知道为什么我得到了一个空名单。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

示例数据:

p <- shapefile(system.file("external/lux.shp", package="raster"))
b <- brick(raster(p), nl=2)
values(b) = sample(2, 200, replace=TRUE)

固定功能:

transitions <- function(poly, rast) {    
    result = vector("list", nrow(poly))
    for (i in 1:nrow(poly)) {  
        clip <- mask(crop(rast, poly[i,]), poly[i,])   
        result[[i]] <- crosstab(clip, digits = 0, long = FALSE, useNA = FALSE)
    }
    return(result)
}

transitions(p, b)

另一种选择是使用提取

e <- extract(b, p)

要像在交叉表中那样制表:

ee <- lapply(e, function(x) aggregate(data.frame(count=rep(1, nrow(x))), data.frame(x), FUN=sum))

要了解最后一行,您需要打开包装。

class(e)
#[1] "list"
length(e)
#[1] 12
e[[1]]
#     layer.1 layer.2
#[1,]       1       1
#[2,]       1       2
#[3,]       2       2
#[4,]       2       1
#[5,]       2       1
#[6,]       1       2
#[7,]       2       2

e是与多边形数相同长度的列表(请参见length(p)

让我们将第一个元素进行汇总并将其聚合以得到包含案例和计数的表格。

x <- e[[1]]

aggregate(data.frame(count=rep(1, nrow(x))), data.frame(x), FUN=sum)
#  layer.1 layer.2 count
#1       1       1     1
#2       2       1     2
#3       1       2     2
#4       2       2     2

通过表格的类似方法(不同之处在于,您可以获得的Freq值为零

as.data.frame(table(x[,1], x[,2]))
#  Var1 Var2 Freq
#1    1    1    1
#2    2    1    2
#3    1    2    2
#4    2    2    2

现在将您喜欢的函数包装到lapply

z <- lapply(e, function(x) aggregate(data.frame(count=rep(1, nrow(x))), data.frame(x), FUN=sum))

进一步说,绑定data.frames并添加标识符以将数据链接回多边形

y <- do.call(rbind, z,)
y$id <- rep(1:length(z), sapply(z, nrow))

head(y)
#  Var1 Var2 Freq id
#1    1    1    1  1
#2    2    1    2  1
#3    1    2    2  1
#4    2    2    2  1
#5    1    1    1  2
#6    2    1    2  2