您可以通过几种不同的方式执行此操作。首先,您需要使数据框具有相同的经度和纬度列名称 lon 和 lat,但这是任意的。完成后,一种方法是生成一个新列表,其中列表的每个元素都有一个数据框和一个范围对象:
library(terra)
library(raster)
library(dplyr)
lat_1 <- c(23.2, 14.5, 28.6)
lon_1 <- c(12.1, 8.5, 2.2)
lat_2 <- c(89.3, 94.4, 72.3)
lon_2 <- c(45.2, 47, 48.5)
coords_1 <- data.frame(lon = lon_1, lat = lat_1)
coords_2 <- data.frame(lon = lon_2, lat = lat_2)
list_coords <- list(coords_1, coords_2)
write_extent <- function(lon, lat) {
max_lat <- ceiling(max(lat))
min_lat <- floor(min(lat))
max_lon <- ceiling(max(lon))
min_lon <- floor(min(lon))
extent <- extent(x = min_lat, xmax=max_lat, ymin = min_lon, ymax=max_lon)
extent
}
res <- lapply(list_coords, function(x){
list(data=x, extent = write_extent(x$lon, x$lat))
})
res
#> [[1]]
#> [[1]]$data
#> lon lat
#> 1 12.1 23.2
#> 2 8.5 14.5
#> 3 2.2 28.6
#>
#> [[1]]$extent
#> class : Extent
#> xmin : 14
#> xmax : 29
#> ymin : 2
#> ymax : 13
#>
#>
#> [[2]]
#> [[2]]$data
#> lon lat
#> 1 45.2 89.3
#> 2 47.0 94.4
#> 3 48.5 72.3
#>
#> [[2]]$extent
#> class : Extent
#> xmin : 72
#> xmax : 95
#> ymin : 45
#> ymax : 49
在上面的输出中,您可以使用res[[1]]$data 获取第一个对象的数据,并使用res[[1]]$extent 获取第一个对象的范围。或者您可以使用 lapply(res, function(x)x$extent) 获得所有范围的列表。另一种选择是将范围存储为数据的属性。这样,它始终遵循周围的数据:
res <- lapply(list_coords, function(x){
e <- write_extent(x$lon, x$lat)
attr(x, "extent") <- e
x
})
res
#> [[1]]
#> lon lat
#> 1 12.1 23.2
#> 2 8.5 14.5
#> 3 2.2 28.6
#>
#> [[2]]
#> lon lat
#> 1 45.2 89.3
#> 2 47.0 94.4
#> 3 48.5 72.3
打印数据框时看不到范围,但您可以通过以下方式为单个数据框检索它:
attr(res[[1]], "extent")
#> class : Extent
#> xmin : 14
#> xmax : 29
#> ymin : 2
#> ymax : 13
或者对于他们所有人:
lapply(res, function(x)attr(x, "extent"))
#> [[1]]
#> class : Extent
#> xmin : 14
#> xmax : 29
#> ymin : 2
#> ymax : 13
#>
#> [[2]]
#> class : Extent
#> xmin : 72
#> xmax : 95
#> ymin : 45
#> ymax : 49
由 reprex package (v2.0.1) 创建于 2022-12-08
虽然我认为设置对象属性不太传统,但this answer 表示这样做并不是坏习惯。