【问题标题】:Use one of the Apply Functions instead of a nested for loop in R在 R 中使用应用函数之一而不是嵌套的 for 循环
【发布时间】:2016-07-07 04:35:15
【问题描述】:

作为一个 R 新手,我认为是时候摆脱 for 循环并进入应用函数了。我正在为这段代码苦苦挣扎,想知道是否有人可以提供帮助。

我有一个函数:

earth.dist <- function (long1, lat1, long2, lat2)
{


rad <- pi/180
  a1 <- lat1 * rad
  a2 <- long1 * rad
  b1 <- lat2 * rad
  b2 <- long2 * rad
  dlon <- b2 - a2
  dlat <- b1 - a1
  a <- (sin(dlat/2))^2 + cos(a1) * cos(b1) * (sin(dlon/2))^2
  c <- 2 * atan2(sqrt(a), sqrt(1 - a))
  R <- 6378.145
  d <- R * c
  return(d)
}

现在我有两个不同的数据集,一个包含预先确定的大城市列表及其经度/纬度坐标,另一个具有美国的随机位置及其经度/纬度坐标。我写的for循环基本上计算随机位置的每个长/纬度坐标与预定大城市的长/纬度坐标之间的差异,并将随机位置置于最近城市所在的州。每个城市在预先确定的列表中,旁边有一个州,该州被插入到随机城市电子表格的新列中。

有没有办法可以使用 apply 来执行此循环?这个循环确实可以解决问题,但它又长又笨重,我知道应用函数可以做得更好。

这是循环:

for(i in 1:nrow(randomlocations)){
  vec<-vector()
  for(j in 1:nrow(predeterminedcities)){
    a<-earth.dist(randomlocations$long[i],randomlocations$lat[i], predeterminedcities$long[j], predeterminedcities$lat[j])
    vec[[j]]<-a
  }
  ind<- as.numeric(which.min(vec))
  randomlocations$state[i]<-as.character(predeterminedcities$STATE[ind])
  print(i)
  }

【问题讨论】:

  • 看来earth.dist 将接受纬度和经度向量。如果这是真的,请一次性输入预定城市的整个向量:a&lt;-earth.dist(randomlocations$long[i],randomlocations$lat[i], predeterminedcities$long, predeterminedcities$lat)
  • 谢谢@Imo!您知道我如何知道使用这种技术的距离最短的行或预定城市吗?
  • 向量的输出(如果它对向量起作用)将按预定城市排序,因此您可以使用这些位置来提取该信息。如果不熟悉,不妨看看which.min

标签: r apply


【解决方案1】:

由于您的函数已经矢量化,您可以使用outer 通过将索引传递到数据帧来计算距离矩阵。通过max.col 弹出该结果以找到最小距离的索引,然后使用它来查找状态名称:

#fake test data
randomlocations <- data.frame(lon=runif(100, -80,-70), lat=runif(100, 45,75))
predeterminedcities <- head(randomlocations, 50)
predeterminedcities$STATE <- state.name

randomlocations$state <- predeterminedcities[
  max.col( -
    outer(1:nrow(randomlocations), 1:nrow(predeterminedcities), 
      function(i,j) earth.dist(randomlocations$lon[i], randomlocations$lat[i], 
                             predeterminedcities$lon[j], predeterminedcities$lat[j])
    )
  ), "STATE"]

如果变量名更短,这将很容易放在一行中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 2014-05-19
    相关资源
    最近更新 更多