所以我正在创建映射函数,用点绘制各个端口的坐标。我想创建一个功能,允许用户选择他们想要标记的端口,然后改变标签位置。
以下是各种端口及其坐标:
Labels Lon Lat
1 Halifax, NS -63.59341 44.68068
2 St. John's, NL -52.73304 47.59341
3 Saint John, NB -66.05236 45.27925
4 Portland, ME -70.24435 43.68068
5 Woods Hole, MA -70.68068 41.62832
6 Nuuk, Greenland -51.75049 64.17453
7 Boston, MA -71.08727 42.36652
我的功能:
port.label <- function (pos1, cex1 = 0.6, offset1 = 0.2, col1 = "deeppink") {
port.file<-read.csv("V:/Science/Finalised Map Files/Ports.csv")
Lon <- port.file$Lon
Lat <- port.file$Lat
Lab <- paste(port.file$Lab)
a <- locator()
ay <- unlist(a[2])
aylab <- sapply (ay, function (x) which.min (abs (x - Lat)))
b <- for (i in (1:length (aylab))) {
text (x = Lon [aylab[i]], y = Lat [aylab[i]], labels = Lab [aylab[i]],
pos = pos1, cex = cex1, offset = offset1, col = col1)
}
}
现在当我尝试使用:port.label(pos1=c(1,2,3,4))
运行它后点击四个点后,它仅使用第一个值(1)返回标签,因此低于该点。所以它只取第一个值。我尝试将pos1长度设置为与点击的端口数相关,但这也无济于事。
为什么它只采用第一个pos1值而不是整个向量的任何想法? 谢谢。
答案 0 :(得分:1)
pos=pos1[i]
进行调用。不幸的是,然后只用1个参数调用port.label就需要额外检查pos1()长度。比如说,您希望所有标签位于同一位置,底部,因此您可以调用port.label( pos1= 1 )
。使用i=2
,pos1[i]
将获取值NA
。因此,如果长度等于1,则必须展开pos1
。
这样称呼它会更有效:
port.label <- function (pos1, cex1 = 0.6, offset1 = 0.2, col1 = "deeppink") {
port.file<-read.csv("V:/Science/Finalised Map Files/Ports.csv")
Lon <- port.file$Lon
Lat <- port.file$Lat
Lab <- paste(port.file$Lab)
a <- locator()
ay <- unlist(a[2])
aylab <- sapply (ay, function (x) which.min (abs (x - Lat)))
text( x= Lon[aylab], y= Lat[aylab], labels= Lab[aylab],
pos= pos1, cex= cex1, offset= offset1, col= col1 )
}
答案 1 :(得分:0)
使用dput
以便于读者在R中运行的形式输出数据很有帮助。
mydat <- structure(list(Lab = c("Halifax, NS", "St. John's, NL", "Saint John, NB",
"Portland, ME", "Woods Hole, MA", "Nuuk, Greenland", "Boston, MA"),
Lon = c(-63.59341, -52.73304, -66.05236, -70.24435, -70.68068, -51.75049, -71.08727),
Lat = c(44.68068, 47.59341, 45.27925, 43.68068, 41.62832, 64.17453, 42.36652)),
.Names = c("Labels", "Lon", "Lat"), class = "data.frame", row.names = c(NA, -7L))
我一点也不清楚为什么你会想要一个这样做的功能。我认为可能有更好的方法去做你真正想做的事情。但是,这是尝试修改您的代码,以便它做你想要的。我使用identify()
函数作为@droopy建议。
port.label <- function (data, posn, cex1=0.6, offset1=0.2, col1="deeppink") {
j <- identify(mydat$Lon, mydat$Lat, mydat$Lab, plot=FALSE)
for(i in 1:length(j)) {
text(x=data$Lon[j[i]], y=data$Lat[j[i]], labels=data$Lab[j[i]], pos=posn[i], cex=cex1, offset=offset1, col=col1)
}
}
plot(mydat$Lon, mydat$Lat)
port.label(mydat, posn=c(1, 2, 3, 4))