【问题标题】:Create a value associated with a member of each list and store it with that member in R创建一个与每个列表的成员关联的值,并将其与该成员一起存储在 R 中
【发布时间】:2022-12-17 22:21:25
【问题描述】:

我有许多数据帧的列表,所有格式都相同。对于此列表中的每个成员,我想生成一个空间范围,并将其与该数据框一起存储(此数据都是纬度/经度数据,我正在使用 terra 包中的函数来分析它)。我在使用列表方面不是很有经验,所以我采取了以下尝试来生成它:

library(terra)
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_1, lat_1)
coords_2 <- data.frame(lon_2, 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 = c(max_lat, min_lat, max_lon, min_lon))
}

但是,此函数有错误,我无法概念化如何将与列表中每个成员对应的空间范围存储到该特定列表中——我应该使用 mutate() 吗?我不应该设计一个功能而是使用 lapply 吗?

【问题讨论】:

    标签: r list function dplyr terra


    【解决方案1】:

    您可以通过几种不同的方式执行此操作。首先,您需要使数据框具有相同的经度和纬度列名称 lonlat,但这是任意的。完成后,一种方法是生成一个新列表,其中列表的每个元素都有一个数据框和一个范围对象:

    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 表示这样做并不是坏习惯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-30
      • 1970-01-01
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      相关资源
      最近更新 更多