【发布时间】:2016-12-01 06:54:19
【问题描述】:
我是 R 的新手,但我听说使用 for 循环确实是个坏主意。我有使用它们的工作代码,但我想改进它,因为大数据非常慢。我已经有了一些如何改进算法的想法,但我不知道如何对其进行矢量化,或者不使用for 循环。
我只是将 lat/lng 点分组为一个以半径为参数的圆。
函数的示例输出(仅填充 circle_id 列中的值),半径设置为 100 米:
[1] "Locations: "
latitude longitude sensor_time sensor_time2 circle_id
48.15144 17.07569 1447149703 2015-11-10 11:01:43 1
48.15404 17.07452 1447149743 2015-11-10 11:02:23 2
48.15277 17.07514 1447149762 2015-11-10 11:02:42 3
48.15208 17.07538 1447149771 2015-11-10 11:02:51 1
48.15461 17.07560 1447149773 2015-11-10 11:02:53 4
48.15139 17.07562 1447149811 2015-11-10 11:03:31 1
48.15446 17.07517 1447149866 2015-11-10 11:04:26 2
48.15266 17.07330 1447149993 2015-11-10 11:06:33 5
所以我有 2 个 for 循环,loop1 遍历每一行,loop2 遍历每个先前的 circle_id,并检查 loop1 的当前位置是否在 loop2 的现有圆的半径内。每个 circle_id 的中心是在所有先前的半径之外找到的第一个位置。
代码如下:
init_circles = function(datfr, radius) {
cnt = 1
datfr$circle_id[1] = 1
longitude = datfr$longitude[1]
latitude = datfr$latitude[1]
circle_id = datfr$circle_id[1]
datfr2 <- data.frame(longitude, latitude, circle_id)
for (i in 2:NROW(datfr)) {
for (j in 1:NROW(datfr2)) {
tmp = distHaversine(c(datfr$longitude[i],datfr$latitude[i]) ,c(datfr2$longitude[j],datfr2$latitude[j]))
if (tmp < radius){
datfr$circle_id[i] = datfr2$circle_id[j]
break
}
}
if (datfr$circle_id[i]<1){
cnt = cnt +1
datfr$circle_id[i] = cnt
datfr2[nrow(datfr2)+1,] = c(datfr$longitude[i],datfr$latitude[i],datfr$circle_id[i])
}
}
return(datfr)
}
datfr 是没有设置circle_id 的输入数据框,datfr2 是包含已有圆圈的临时数据框。
你可以看到这些圆圈的用途,上面的红色圆圈有 21 个其他位置适合它的半径 (21 + 1 original = 22)
非常感谢您的帮助, 阿莱娜
【问题讨论】:
标签: r optimization