R语言 从SF对象中提取单个特征

vsdwdz23  于 2023-05-20  发布在  其他
关注(0)|答案(3)|浏览(179)

我正在寻找一个有效的方法,从一个SF对象提取一个单一的功能,当功能作为变量名。如果我们有一个sf-object,比如:

g = st_as_sf(data.frame(x = 1:5, y = 5:1, a = 6:10, b = 11:15), coords = c("x", "y"))

我们可以很容易地用g$a提取列a。但是,我想知道如果我想使用变量colname = "a",提取列a的最有效方法是什么。g[,colname]将返回一个sf-object,其中a是唯一的特征。可以将对象转换为data.frame,然后使用data.frame(g)[, colname]提取列。然而,这不是非常有效的。如microbenchmark所示:

microbenchmark(g$a, data.frame(g)[, "a"])

当然,在这种情况下,纳秒很少引起人们的兴趣,但对于频繁提取较大对象,对data.frame(g)的调用将对总运行时间产生影响。在这种情况下,除了创建另一个对象gg=data.frame(g)之外,还有更有效的方法吗?

hi3rlvi2

hi3rlvi21#

由于sf仍然是data.frame(或tibble),因此不需要手动转换。只需在[][[]]之间切换,具体取决于您是否需要一个列作为矢量或sf对象,该对象具有单个特征,其中几何体仍然附加:

ne <- rnaturalearth::ne_countries(returnclass = "sf")
names(ne)[1:10]
#>  [1] "featurecla" "scalerank"  "labelrank"  "sovereignt" "sov_a3"    
#>  [6] "adm0_dif"   "level"      "type"       "admin"      "adm0_a3"
(sel_col <- names(ne)[9])
#> [1] "admin"

# sf with 1 feature colum and geomery column:
ne[sel_col] |> str()
#> Classes 'sf' and 'data.frame':   177 obs. of  2 variables:
#>  $ admin   : chr  "Fiji" "United Republic of Tanzania" "Western Sahara" "Canada" ...
#>  $ geometry:sfc_MULTIPOLYGON of length 177; first list element: List of 3
#>   ..$ :List of 1
#>   .. ..$ : num [1:8, 1:2] 180 180 179 179 179 ...
#>   ..$ :List of 1
#>   .. ..$ : num [1:9, 1:2] 178 178 179 179 178 ...
#>   ..$ :List of 1
#>   .. ..$ : num [1:5, 1:2] -180 -180 -180 -180 -180 ...
#>   ..- attr(*, "class")= chr [1:3] "XY" "MULTIPOLYGON" "sfg"
#>  - attr(*, "sf_column")= chr "geometry"
#>  - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA
#>   ..- attr(*, "names")= chr "admin"

# feature as a vector: 
ne[[sel_col]] |> str()
#>  chr [1:177] "Fiji" "United Republic of Tanzania" "Western Sahara" "Canada" ...

创建于2023-05-12带有reprex v2.0.2

iovurdzv

iovurdzv2#

怎么样

colname = 'a'
g[c(colname, 'geometry')]

...如果你想保留属性a加上几何体?
如果实际上要删除几何体(将要素转换为非空间数据框行),可以通过以下方式执行:

as.data.frame(us)[colname]
9udxz4iz

9udxz4iz3#

我想到了几种可能性,但从基准测试的Angular 来看,没有一种是真正的游戏改变者。

microbenchmark(g$a, 
               data.frame(g)[, "a"], 
               g[, "a", drop = T],
               st_drop_geometry(g)[, "a"],
               data.table::as.data.table(g)[, "a"],
               dplyr::pull(g, "a")
               )

{sf}[方法(参数drop设置为true)似乎是最快的,但仍然不能与美元符号运算符相比。

相关问题