R:如何使用应用于 data.frame 列的 st_point() 创建点?
R: How to create points using st_point() applied to columns of data.frame?
在 R 中,我尝试使用包 sf 中的 st_point() 创建点。
我的输入是 data.frame,其中一列是 x 坐标,另一列是 y 坐标:
# Code to generate input
library(sf)
N <- 10
df <- data.frame(x=rnorm(N),y=rnorm(N))
我想做的只是
# Code to generate examplar output
L <- list()
for (i in 1:N)
{
L[[i]] <- st_point(c(df$x[i],df$y[i]))
}
st_sfc(L)
但是我正在尝试使用 mapply(.)
来代替循环
mapply(function(x,y) sum(c(x,y)),df$x,df$y)
mapply(function(x,y) st_point(c(x,y)),df$x,df$y)
这适用于添加列但不适用于创建空间点。
我的问题有两个:(1) 为什么使用 mapply 会失败? (2) 什么是有效的方法?
如果您阅读 ?mapply
的文档,您会发现默认情况下它简化了结果,returns 在这种情况下是一个矩阵。你可以告诉它不要简化。
# Code to generate input
library(sf)
N <- 10
df <- data.frame(x=rnorm(N),y=rnorm(N))
test <- mapply(function(x,y) st_point(c(x,y)),df$x,df$y)
str(test)
# num [1:2, 1:10] -1.42485 0.00776 -0.78035 -0.03221 0.30925 ...
test <- mapply(function(x,y) st_point(c(x,y)),df$x,df$y,SIMPLIFY = FALSE)
str(test)
# List of 10
# $ : 'XY' num [1:2] -1.42485 0.00776
# $ : 'XY' num [1:2] -0.7804 -0.0322
# $ : 'XY' num [1:2] 0.309 -0.541
# $ : 'XY' num [1:2] 0.459 -0.614
# $ : 'XY' num [1:2] -2.919 -0.169
# $ : 'XY' num [1:2] 0.689 0.168
# $ : 'XY' num [1:2] -1.066 0.711
# $ : 'XY' num [1:2] 1.09 0.925
# $ : 'XY' num [1:2] 0.756 0.81
# $ : 'XY' num [1:2] -1.17 -2.13
如果您无论如何都要在数据框中存储内容,您可以考虑使用 dplyr
方法。但是,您需要将这些点包装在 list() 中才能使 dplyr 突变起作用。
library(dplyr)
test <- df %>%
rowwise() %>%
mutate(point = list(st_point(c(x,y))))
str(test$point)
# List of 10
# $ : 'XY' num [1:2] -1.42485 0.00776
# $ : 'XY' num [1:2] -0.7804 -0.0322
# $ : 'XY' num [1:2] 0.309 -0.541
# $ : 'XY' num [1:2] 0.459 -0.614
# $ : 'XY' num [1:2] -2.919 -0.169
# $ : 'XY' num [1:2] 0.689 0.168
# $ : 'XY' num [1:2] -1.066 0.711
# $ : 'XY' num [1:2] 1.09 0.925
# $ : 'XY' num [1:2] 0.756 0.81
# $ : 'XY' num [1:2] -1.17 -2.13
关于问题 2(什么是有效的方法?),
这是一个完全基于 sf 包函数
的解决方案
library(sf)
N <- 10
df <- data.frame(x=rnorm(N),y=rnorm(N))
df |>
as.matrix() |>
st_multipoint() |>
st_sfc() |>
st_cast('POINT')
#> Geometry set for 10 features
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: -0.612779 ymin: -1.136853 xmax: 2.212084 ymax: 2.042055
#> CRS: NA
#> First 5 geometries:
#> POINT (0.8364834 -0.3604207)
#> POINT (-0.5956698 -0.4816545)
#> POINT (0.1144735 -0.9178366)
#> POINT (2.212084 1.311319)
#> POINT (-0.04635354 1.423213)
由 reprex package (v2.0.0)
于 2021-07-05 创建
在 R 中,我尝试使用包 sf 中的 st_point() 创建点。
我的输入是 data.frame,其中一列是 x 坐标,另一列是 y 坐标:
# Code to generate input
library(sf)
N <- 10
df <- data.frame(x=rnorm(N),y=rnorm(N))
我想做的只是
# Code to generate examplar output
L <- list()
for (i in 1:N)
{
L[[i]] <- st_point(c(df$x[i],df$y[i]))
}
st_sfc(L)
但是我正在尝试使用 mapply(.)
来代替循环 mapply(function(x,y) sum(c(x,y)),df$x,df$y)
mapply(function(x,y) st_point(c(x,y)),df$x,df$y)
这适用于添加列但不适用于创建空间点。
我的问题有两个:(1) 为什么使用 mapply 会失败? (2) 什么是有效的方法?
如果您阅读 ?mapply
的文档,您会发现默认情况下它简化了结果,returns 在这种情况下是一个矩阵。你可以告诉它不要简化。
# Code to generate input
library(sf)
N <- 10
df <- data.frame(x=rnorm(N),y=rnorm(N))
test <- mapply(function(x,y) st_point(c(x,y)),df$x,df$y)
str(test)
# num [1:2, 1:10] -1.42485 0.00776 -0.78035 -0.03221 0.30925 ...
test <- mapply(function(x,y) st_point(c(x,y)),df$x,df$y,SIMPLIFY = FALSE)
str(test)
# List of 10
# $ : 'XY' num [1:2] -1.42485 0.00776
# $ : 'XY' num [1:2] -0.7804 -0.0322
# $ : 'XY' num [1:2] 0.309 -0.541
# $ : 'XY' num [1:2] 0.459 -0.614
# $ : 'XY' num [1:2] -2.919 -0.169
# $ : 'XY' num [1:2] 0.689 0.168
# $ : 'XY' num [1:2] -1.066 0.711
# $ : 'XY' num [1:2] 1.09 0.925
# $ : 'XY' num [1:2] 0.756 0.81
# $ : 'XY' num [1:2] -1.17 -2.13
如果您无论如何都要在数据框中存储内容,您可以考虑使用 dplyr
方法。但是,您需要将这些点包装在 list() 中才能使 dplyr 突变起作用。
library(dplyr)
test <- df %>%
rowwise() %>%
mutate(point = list(st_point(c(x,y))))
str(test$point)
# List of 10
# $ : 'XY' num [1:2] -1.42485 0.00776
# $ : 'XY' num [1:2] -0.7804 -0.0322
# $ : 'XY' num [1:2] 0.309 -0.541
# $ : 'XY' num [1:2] 0.459 -0.614
# $ : 'XY' num [1:2] -2.919 -0.169
# $ : 'XY' num [1:2] 0.689 0.168
# $ : 'XY' num [1:2] -1.066 0.711
# $ : 'XY' num [1:2] 1.09 0.925
# $ : 'XY' num [1:2] 0.756 0.81
# $ : 'XY' num [1:2] -1.17 -2.13
关于问题 2(什么是有效的方法?), 这是一个完全基于 sf 包函数
的解决方案library(sf)
N <- 10
df <- data.frame(x=rnorm(N),y=rnorm(N))
df |>
as.matrix() |>
st_multipoint() |>
st_sfc() |>
st_cast('POINT')
#> Geometry set for 10 features
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: -0.612779 ymin: -1.136853 xmax: 2.212084 ymax: 2.042055
#> CRS: NA
#> First 5 geometries:
#> POINT (0.8364834 -0.3604207)
#> POINT (-0.5956698 -0.4816545)
#> POINT (0.1144735 -0.9178366)
#> POINT (2.212084 1.311319)
#> POINT (-0.04635354 1.423213)
由 reprex package (v2.0.0)
于 2021-07-05 创建