在terra包中用rast(type=xyz)将含时间列的data.frame转为多图层SpatRaster
问题
我有一个包含longitude、latitude、date、vals列的CSV数据框:
df <- data.frame(longitude=rep(c(10.5,11,12),10), latitude=rep(c(10.5,11,12),10), date= as.Date(rep(c("2012-01-01", "2012-02-01", "2012-03-01"), 10)), vals=rnorm(30,10,5))
我希望使用S4方法rast(x, type="xyz", crs="", digits=6, extent=NULL)将其转换为SpatRaster,其中每个date对应一个单独图层。
去掉date列后可以成功转换:
df.subset <- dplyr::select(df,-date) tmp <- terra::rast(df.subset, type="xyz")
但尝试按date拆分SpatRaster时出现错误:Error in .local(x, f, ...) : length(f) == nlyr(x) is not TRUE,代码如下:
split(tmp, as.factor(df$date))
我想到一种循环方法:
- 按
date拆分数据框:split(df, c("2012-01-01", "2012-02-01", "2012-03-01")) - 为每个
date创建单独的SpatRaster - 使用
merge合并带命名图层的SpatRaster
请问在terra包中有没有更简洁的实现方式?
解决方案
有两种更简洁的实现方式,无需手动循环:
方法一:宽格式转换法
先将长格式数据转为宽格式,让每个日期对应单独的数值列,之后直接用terra::rast的xyz类型转换即可,每一列会自动成为一个栅格图层:
library(terra) library(tidyr) library(dplyr) # 转换为宽格式:经纬度作为标识,日期作为列名,vals为对应值 df_wide <- df %>% pivot_wider(names_from = date, values_from = vals) # 生成多图层SpatRaster r <- rast(df_wide, type = "xyz")
方法二:分组批量创建法
结合dplyr的分组拆分功能,批量生成单个日期的栅格后,用c()合并为多图层对象(比merge更高效):
library(terra) library(dplyr) # 按日期分组,每组生成单个图层的栅格,再合并 r <- df %>% group_split(date) %>% lapply(function(group) rast(group[, c("longitude", "latitude", "vals")], type = "xyz")) %>% do.call(c, .) # 给图层命名为对应日期 names(r) <- unique(df$date)
原错误原因
你之前用split(tmp, as.factor(df$date))报错,是因为split()要求分组因子的长度必须和栅格的图层数一致。但你创建的tmp只有1个图层,而df$date有30个元素,二者长度不匹配,因此触发错误。
内容的提问来源于stack exchange,提问作者Thomas Moore
相关产品推荐
相关产品推荐

