为什么我在使用 ```terra::extract``` 提取栅格数据时会丢失列?
Why am I losing columns when extracting raster data with ```terra::extract```?
我创建了一个栅格堆栈,其中的栅格包含不同的植被测量值(即树冠高度、植物密度)。我从该栅格堆栈中提取数据到包含 GPS 点和相应数据的 SpatVector。输出包含栅格数据,但不包含任何 SpatVector 数据。下面的示例代码。我不确定如何将栅格数据添加到问题中。
structure(list(Id = c("A1", "A1", "A1", "A1", "A1", "A1", "A1",
"A1", "A1", "A1"), DateTime_Local = c("2019-06-18 14:00:00",
"2019-06-18 14:30:00", "2019-06-18 15:00:00", "2019-06-18 15:30:00",
"2019-06-18 16:00:00", "2019-06-18 16:30:00", "2019-06-18 17:00:00",
"2019-06-18 17:30:00", "2019-06-18 18:00:00", "2019-06-18 18:30:00"
), Temp_C = c(23.484, 23.388, 23.196, 23.677, 24.738, 24.738,
24.641, 26.097, 27.37, 28.357), Temp_F = c(74.2712, 74.0984,
73.7528, 74.6186, 76.5284, 76.5284, 76.3538, 78.9746, 81.266,
83.0426), Type = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Long = c(-97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153, -97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153), Lat = c(26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955, 26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955), Long.1 = c(651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045), Lat.1 = c(2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244
)), row.names = c(NA, -10L), class = "data.frame")
BG_vect <- vect(BG.sf) #SF object containing GPS coordinates and point data
BG.extracted <- terra::extract(veg_stk, BG_vect, fun = mean)
summary(BG.extracted)
我认为您需要做的就是将 terra::extract()
中的结果 data.frame
合并回您的 SpatVector
对象。我用您的数据创建了一个可重现的示例。请注意,您的空间数据似乎只包含一个点位置,因此我用一些随机选择的位置更改了“Lat”和“Long”列。我还假设这些数据位于 WGS84 Lat/Long 坐标系 (EPSG:4269) 中。由此我创建了一个假的树冠高度数据栅格。
library(terra)
library(sf)
spvect<-structure(list(Id = c("A1", "A1", "A1", "A1", "A1", "A1", "A1",
"A1", "A1", "A1"), DateTime_Local = c("2019-06-18 14:00:00",
"2019-06-18 14:30:00", "2019-06-18 15:00:00", "2019-06-18 15:30:00",
"2019-06-18 16:00:00", "2019-06-18 16:30:00", "2019-06-18 17:00:00",
"2019-06-18 17:30:00", "2019-06-18 18:00:00", "2019-06-18 18:30:00"
), Temp_C = c(23.484, 23.388, 23.196, 23.677, 24.738, 24.738,
24.641, 26.097, 27.37, 28.357), Temp_F = c(74.2712, 74.0984,
73.7528, 74.6186, 76.5284, 76.5284, 76.3538, 78.9746, 81.266,
83.0426), Type = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Long = c(-97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153, -97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153), Lat = c(26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955, 26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955), Long.1 = c(651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045), Lat.1 = c(2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244
)), row.names = c(NA, -10L), class = "data.frame")
spvect$Long<-runif(nrow(spvect), -97.5, -96.5)
spvect$Lat<-runif(nrow(spvect), 26, 27)
BG.sf<-sf::st_as_sf(spvect, coords=c("Long", "Lat"), crs=4269)
BG.sf[,"Ind"]<-rownames(BG.sf)
BG.vect<-vect(BG.sf)
rst<-rast(extent=ext(BG.vect), nrow=100, ncol=100, crs=crs(BG.vect))
values(rst)<-rnorm(10000, 100, 12)
names(rst)<-"Canopy Height"
extrctd<-extract(rst,BG.vect)
BG.Final<-terra::merge(BG.vect, extrctd, by.x="Ind", by.y="ID")
您可以使用 cbind
.
将原始点数据与提取的值结合起来
示例数据
library(terra)
df <- data.frame(id=1:5, Long = 1:5, Lat=1:5, var=letters[1:5])
df
# id Long Lat var
#1 1 1 1 a
#2 2 2 2 b
#3 3 3 3 c
#4 4 4 4 d
#5 5 5 5 e
r <- rast(xmin=0, xmax=6, ymin=0, ymax=6, nlyr=2, res=.5, names=c("A", "B"))
set.seed(0)
values(r) <- sample(size(r))
直接使用 data.frame
中的 x(经度)和 y(纬度)坐标从栅格中提取值会很有效
e1 <- extract(r, df[, c("Long", "Lat")])
e1
# ID A B
#1 1 273 46
#2 2 201 18
#3 3 51 238
#4 4 141 27
#5 5 115 106
但是你也可以先创建一个SpatVector
v <- vect(df, c("Long", "Lat"))
e2 <- extract(r, v)
在任何一种情况下,您都可以 cbind
将结果发送到 data.frame 或 SpatVector。
cbind(df, e1[,-1])
# id Long Lat var A B
#1 1 1 1 a 273 46
#2 2 2 2 b 201 18
#3 3 3 3 c 51 238
#4 4 4 4 d 141 27
#5 5 5 5 e 115 106
cbind(v, e2[,-1])
# class : SpatVector
# geometry : points
# dimensions : 5, 4 (geometries, attributes)
# extent : 1, 5, 1, 5 (xmin, xmax, ymin, ymax)
# coord. ref. :
# names : id var A B
# type : <int> <chr> <int> <int>
# values : 1 a 273 46
# 2 b 201 18
# 3 c 51 238
所以回答你的问题:你没有丢失专栏;只是输入数据没有在输出中复制。此外,虽然您可以在此处使用 merge
,但效率很低。
我创建了一个栅格堆栈,其中的栅格包含不同的植被测量值(即树冠高度、植物密度)。我从该栅格堆栈中提取数据到包含 GPS 点和相应数据的 SpatVector。输出包含栅格数据,但不包含任何 SpatVector 数据。下面的示例代码。我不确定如何将栅格数据添加到问题中。
structure(list(Id = c("A1", "A1", "A1", "A1", "A1", "A1", "A1",
"A1", "A1", "A1"), DateTime_Local = c("2019-06-18 14:00:00",
"2019-06-18 14:30:00", "2019-06-18 15:00:00", "2019-06-18 15:30:00",
"2019-06-18 16:00:00", "2019-06-18 16:30:00", "2019-06-18 17:00:00",
"2019-06-18 17:30:00", "2019-06-18 18:00:00", "2019-06-18 18:30:00"
), Temp_C = c(23.484, 23.388, 23.196, 23.677, 24.738, 24.738,
24.641, 26.097, 27.37, 28.357), Temp_F = c(74.2712, 74.0984,
73.7528, 74.6186, 76.5284, 76.5284, 76.3538, 78.9746, 81.266,
83.0426), Type = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Long = c(-97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153, -97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153), Lat = c(26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955, 26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955), Long.1 = c(651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045), Lat.1 = c(2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244
)), row.names = c(NA, -10L), class = "data.frame")
BG_vect <- vect(BG.sf) #SF object containing GPS coordinates and point data
BG.extracted <- terra::extract(veg_stk, BG_vect, fun = mean)
summary(BG.extracted)
我认为您需要做的就是将 terra::extract()
中的结果 data.frame
合并回您的 SpatVector
对象。我用您的数据创建了一个可重现的示例。请注意,您的空间数据似乎只包含一个点位置,因此我用一些随机选择的位置更改了“Lat”和“Long”列。我还假设这些数据位于 WGS84 Lat/Long 坐标系 (EPSG:4269) 中。由此我创建了一个假的树冠高度数据栅格。
library(terra)
library(sf)
spvect<-structure(list(Id = c("A1", "A1", "A1", "A1", "A1", "A1", "A1",
"A1", "A1", "A1"), DateTime_Local = c("2019-06-18 14:00:00",
"2019-06-18 14:30:00", "2019-06-18 15:00:00", "2019-06-18 15:30:00",
"2019-06-18 16:00:00", "2019-06-18 16:30:00", "2019-06-18 17:00:00",
"2019-06-18 17:30:00", "2019-06-18 18:00:00", "2019-06-18 18:30:00"
), Temp_C = c(23.484, 23.388, 23.196, 23.677, 24.738, 24.738,
24.641, 26.097, 27.37, 28.357), Temp_F = c(74.2712, 74.0984,
73.7528, 74.6186, 76.5284, 76.5284, 76.3538, 78.9746, 81.266,
83.0426), Type = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Long = c(-97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153, -97.47462153,
-97.47462153, -97.47462153, -97.47462153, -97.47462153), Lat = c(26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955, 26.58459955,
26.58459955, 26.58459955, 26.58459955, 26.58459955), Long.1 = c(651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045, 651903.662642045, 651903.662642045, 651903.662642045,
651903.662642045), Lat.1 = c(2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244,
2941332.22211244, 2941332.22211244, 2941332.22211244, 2941332.22211244
)), row.names = c(NA, -10L), class = "data.frame")
spvect$Long<-runif(nrow(spvect), -97.5, -96.5)
spvect$Lat<-runif(nrow(spvect), 26, 27)
BG.sf<-sf::st_as_sf(spvect, coords=c("Long", "Lat"), crs=4269)
BG.sf[,"Ind"]<-rownames(BG.sf)
BG.vect<-vect(BG.sf)
rst<-rast(extent=ext(BG.vect), nrow=100, ncol=100, crs=crs(BG.vect))
values(rst)<-rnorm(10000, 100, 12)
names(rst)<-"Canopy Height"
extrctd<-extract(rst,BG.vect)
BG.Final<-terra::merge(BG.vect, extrctd, by.x="Ind", by.y="ID")
您可以使用 cbind
.
示例数据
library(terra)
df <- data.frame(id=1:5, Long = 1:5, Lat=1:5, var=letters[1:5])
df
# id Long Lat var
#1 1 1 1 a
#2 2 2 2 b
#3 3 3 3 c
#4 4 4 4 d
#5 5 5 5 e
r <- rast(xmin=0, xmax=6, ymin=0, ymax=6, nlyr=2, res=.5, names=c("A", "B"))
set.seed(0)
values(r) <- sample(size(r))
直接使用 data.frame
中的 x(经度)和 y(纬度)坐标从栅格中提取值会很有效e1 <- extract(r, df[, c("Long", "Lat")])
e1
# ID A B
#1 1 273 46
#2 2 201 18
#3 3 51 238
#4 4 141 27
#5 5 115 106
但是你也可以先创建一个SpatVector
v <- vect(df, c("Long", "Lat"))
e2 <- extract(r, v)
在任何一种情况下,您都可以 cbind
将结果发送到 data.frame 或 SpatVector。
cbind(df, e1[,-1])
# id Long Lat var A B
#1 1 1 1 a 273 46
#2 2 2 2 b 201 18
#3 3 3 3 c 51 238
#4 4 4 4 d 141 27
#5 5 5 5 e 115 106
cbind(v, e2[,-1])
# class : SpatVector
# geometry : points
# dimensions : 5, 4 (geometries, attributes)
# extent : 1, 5, 1, 5 (xmin, xmax, ymin, ymax)
# coord. ref. :
# names : id var A B
# type : <int> <chr> <int> <int>
# values : 1 a 273 46
# 2 b 201 18
# 3 c 51 238
所以回答你的问题:你没有丢失专栏;只是输入数据没有在输出中复制。此外,虽然您可以在此处使用 merge
,但效率很低。