获取一个参数来获取多个值 - R

时间:2013-07-10 14:45:12

标签: r function vector arguments

所以我正在创建映射函数,用点绘制各个端口的坐标。我想创建一个功能,允许用户选择他们想要标记的端口,然后改变标签位置。

以下是各种端口及其坐标:

           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值而不是整个向量的任何想法? 谢谢。

2 个答案:

答案 0 :(得分:1)

嗯,因为每次调用text()都会用完整的向量调用它。由于每次调用仅针对一个标签,因此您需要使用pos=pos1[i]进行调用。不幸的是,然后只用1个参数调用port.label就需要额外检查pos1()长度。比如说,您希望所有标签位于同一位置,底部,因此您可以调用port.label( pos1= 1 )。使用i=2pos1[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))