从 X Y 点创建空间线时保留起点和终点 ID
Retain start and end IDs when creating spatial lines from X Y points
以下代码将创建连接数据集中所有 x/y 点的 SpatialLines。但是,每个 x/y 点都有一个唯一的 ID。我需要将 x/y 的起点和终点 ID 保留为连接它们的每个 SpatialLines 的 "attributes"(ArcGIS 术语)。
帮助将不胜感激。
我有一个 XY 值数据集,如下所示
x<-c(2,4,6,3,7,9,1)
y<-c(6,4,8,2,9,6,1)
id<-c("a","b","c","d","e","f","g")
dataset<-data.frame(cbind(x,y,id))
dataset$x<-as.numeric(as.character(dataset$x)) #converting from factor to numeric
dataset$y<-as.numeric(as.character(dataset$y))
plot(dataset$x,dataset$y)
复制数据框以涵盖所有可能的组合
dataset<-do.call(rbind, replicate(7, dataset, simplify=FALSE))
现在,创建一个包含所有相同目标点的混合矩阵:
nm=matrix(ncol=3)
for (i in 1:7){
nm<-rbind(nm,do.call(rbind,replicate(7,as.matrix(dataset[i,]),simplify=FALSE)))
}
nm<-nm[-1,]
重命名矩阵的列,使它们有意义,并将现有数据框与新矩阵绑定
colnames(nm)<-c("x2","y2","id.dest")
newds<-cbind(dataset,as.data.frame(nm))
删除重复轨迹:
newds1<-newds[-which(newds$id==newds$id.dest),]
将目标 x 和 y 从因子转换为数字
newds1$x2<-as.numeric(as.character(newds1$x2)) #converting from factor to numeric
newds1$y2<-as.numeric(as.character(newds1$y2))
绘制目标点。 . .与原点相同
plot(newds1$x, newds1$y)
plot(newds1$x2, newds1$y2, col="red")
####*
将起点和终点转换为空间线
用于存储 Lines 对象的原始列表
l <- vector("list", nrow(newds1)) #
这个 l 现在是一个空向量,其中包含由 newds1 的长度 (nrow) 定义的行数
拆分起点坐标和终点坐标以便我可以运行这个脚本
origins<-data.frame(cbind(newds1$x, newds1$y))
destinations<-data.frame(cbind(newds1$x2, newds1$y2))
library(sp)
for (i in seq_along(l)) {
l[[i]] <- Lines(list(Line(rbind(origins[i, ], destinations[i,]))), as.character(i))
}
l.spatial<-SpatialLines(l)
plot(l.spatial, add=T)
对象 newds1 包含起点和终点。但是,从这些起点和终点 (l.spatial) 创建的最终 SpatialLines 不包含对起点和终点的引用。我希望那些 SpatialLines 包含两个 "attribute" 列,它们引用起点和终点的 ID。我认为这是将 newds1(一个数据帧)绑定到 l.spatial(空间线)的问题,但我 运行ning 的代码似乎没有这样做。
正在尝试将开始和结束 ID 在空间上绑定到 l.spatial
row.names(newds1)<-1:length(newds1$id) #renaming rows in the dataframe so they match the spatial object
id<-newds1$id
newds2<-spCbind(l.spatial, id)
我明白了
"Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘spCbind’ for signature ‘"SpatialLines", "factor"’"
简而言之:
newds2 <- SpatialLinesDataFrame(l.spatial, newds1, match.ID = FALSE)
## or you can use the rownames of newds1 in the lines loop)
有 42 条不同的线,通过将每个坐标与彼此坐标匹配一次而制成。
FWIW,您不需要从因子转换为数字:
x <- c(2,4,6,3,7,9,1)
y <- c(6,4,8,2,9,6,1)
id <- c("a","b","c","d","e","f","g")
## don't coerce to character in the
##first place cbind(x, y, id) *must* be
## character and then data.frame
## converts characters to factors
dataset <- data.frame(x = x, y = y, id = id)
还有其他方法可以简化您的任务,但这里有一个相当简单的方法(我认为这就是您所追求的):
x <- c(2,4,6,3,7,9,1)
y <- c(6,4,8,2,9,6,1)
id<-c("a","b","c","d","e","f","g")
## 首先不要强制转换为字符 cbind(x, y, id) must be character
## 然后 data.frame 默认将字符转换为因子
数据集<-data.frame(x = x, y = y, id = id)
l <- vector("list", nrow(dataset) * (nrow(dataset) - 1))
origID <- destID <- character(length(l))
##xy <- as.matrix(dataset[, c("x", "y")])
cnt <- 0
for (i in seq(nrow(dataset))) {
pt0 <- as.matrix(dataset[i, c("x", "y") ])
pts <- dataset[-i, ]
for (j in seq(nrow(pts))) {
cnt <- cnt + 1
l[[cnt]] <- Lines(list(Line(rbind(pt0, as.matrix(pts[j, c("x", "y")])))), as.character(cnt))
destID[cnt] <- pts$id[j]
origID[cnt] <- dataset$id[i]
}
}
x <- SpatialLinesDataFrame(SpatialLines(l), data.frame(dest = destID, orig = origID, row.names = as.character(1:cnt)))
挑出一行进行调查:
itest <- 10
## so for example
as.data.frame(x[itest, ])
index <- c(x$orig[itest], x$dest[itest])
plot(x)
plot(x[itest, ], lwd = 4, add = TRUE)
lines(dataset[index, c("x", "y")], col = "firebrick", lwd = 2)
text(dataset[index, c("x", "y")], label = dataset$id[index], col = "dodgerblue", cex = 4)
以下代码将创建连接数据集中所有 x/y 点的 SpatialLines。但是,每个 x/y 点都有一个唯一的 ID。我需要将 x/y 的起点和终点 ID 保留为连接它们的每个 SpatialLines 的 "attributes"(ArcGIS 术语)。
帮助将不胜感激。
我有一个 XY 值数据集,如下所示
x<-c(2,4,6,3,7,9,1)
y<-c(6,4,8,2,9,6,1)
id<-c("a","b","c","d","e","f","g")
dataset<-data.frame(cbind(x,y,id))
dataset$x<-as.numeric(as.character(dataset$x)) #converting from factor to numeric
dataset$y<-as.numeric(as.character(dataset$y))
plot(dataset$x,dataset$y)
复制数据框以涵盖所有可能的组合
dataset<-do.call(rbind, replicate(7, dataset, simplify=FALSE))
现在,创建一个包含所有相同目标点的混合矩阵:
nm=matrix(ncol=3)
for (i in 1:7){
nm<-rbind(nm,do.call(rbind,replicate(7,as.matrix(dataset[i,]),simplify=FALSE)))
}
nm<-nm[-1,]
重命名矩阵的列,使它们有意义,并将现有数据框与新矩阵绑定
colnames(nm)<-c("x2","y2","id.dest")
newds<-cbind(dataset,as.data.frame(nm))
删除重复轨迹:
newds1<-newds[-which(newds$id==newds$id.dest),]
将目标 x 和 y 从因子转换为数字
newds1$x2<-as.numeric(as.character(newds1$x2)) #converting from factor to numeric
newds1$y2<-as.numeric(as.character(newds1$y2))
绘制目标点。 . .与原点相同
plot(newds1$x, newds1$y)
plot(newds1$x2, newds1$y2, col="red")
####*
将起点和终点转换为空间线
用于存储 Lines 对象的原始列表
l <- vector("list", nrow(newds1)) #
这个 l 现在是一个空向量,其中包含由 newds1 的长度 (nrow) 定义的行数
拆分起点坐标和终点坐标以便我可以运行这个脚本
origins<-data.frame(cbind(newds1$x, newds1$y))
destinations<-data.frame(cbind(newds1$x2, newds1$y2))
library(sp)
for (i in seq_along(l)) {
l[[i]] <- Lines(list(Line(rbind(origins[i, ], destinations[i,]))), as.character(i))
}
l.spatial<-SpatialLines(l)
plot(l.spatial, add=T)
对象 newds1 包含起点和终点。但是,从这些起点和终点 (l.spatial) 创建的最终 SpatialLines 不包含对起点和终点的引用。我希望那些 SpatialLines 包含两个 "attribute" 列,它们引用起点和终点的 ID。我认为这是将 newds1(一个数据帧)绑定到 l.spatial(空间线)的问题,但我 运行ning 的代码似乎没有这样做。
正在尝试将开始和结束 ID 在空间上绑定到 l.spatial
row.names(newds1)<-1:length(newds1$id) #renaming rows in the dataframe so they match the spatial object
id<-newds1$id
newds2<-spCbind(l.spatial, id)
我明白了
"Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘spCbind’ for signature ‘"SpatialLines", "factor"’"
简而言之:
newds2 <- SpatialLinesDataFrame(l.spatial, newds1, match.ID = FALSE)
## or you can use the rownames of newds1 in the lines loop)
有 42 条不同的线,通过将每个坐标与彼此坐标匹配一次而制成。
FWIW,您不需要从因子转换为数字:
x <- c(2,4,6,3,7,9,1)
y <- c(6,4,8,2,9,6,1)
id <- c("a","b","c","d","e","f","g")
## don't coerce to character in the
##first place cbind(x, y, id) *must* be
## character and then data.frame
## converts characters to factors
dataset <- data.frame(x = x, y = y, id = id)
还有其他方法可以简化您的任务,但这里有一个相当简单的方法(我认为这就是您所追求的):
x <- c(2,4,6,3,7,9,1) y <- c(6,4,8,2,9,6,1) id<-c("a","b","c","d","e","f","g") ## 首先不要强制转换为字符 cbind(x, y, id) must be character ## 然后 data.frame 默认将字符转换为因子 数据集<-data.frame(x = x, y = y, id = id)
l <- vector("list", nrow(dataset) * (nrow(dataset) - 1))
origID <- destID <- character(length(l))
##xy <- as.matrix(dataset[, c("x", "y")])
cnt <- 0
for (i in seq(nrow(dataset))) {
pt0 <- as.matrix(dataset[i, c("x", "y") ])
pts <- dataset[-i, ]
for (j in seq(nrow(pts))) {
cnt <- cnt + 1
l[[cnt]] <- Lines(list(Line(rbind(pt0, as.matrix(pts[j, c("x", "y")])))), as.character(cnt))
destID[cnt] <- pts$id[j]
origID[cnt] <- dataset$id[i]
}
}
x <- SpatialLinesDataFrame(SpatialLines(l), data.frame(dest = destID, orig = origID, row.names = as.character(1:cnt)))
挑出一行进行调查:
itest <- 10
## so for example
as.data.frame(x[itest, ])
index <- c(x$orig[itest], x$dest[itest])
plot(x)
plot(x[itest, ], lwd = 4, add = TRUE)
lines(dataset[index, c("x", "y")], col = "firebrick", lwd = 2)
text(dataset[index, c("x", "y")], label = dataset$id[index], col = "dodgerblue", cex = 4)