【发布时间】:2026-01-07 20:50:02
【问题描述】:
我有一个包含 id 和位置的 data.table。例如,这里有一行: (它有 col 和 row 名称,不知道是否重要)
locations<-data.table(c(11,12),c(-159.58,0.2),c(21.901,22.221))
colnames(locations)<-c("id","location_lon","location_lat")
rownames(locations)<-c("1","2")
然后我想遍历这些行并将它们与另一个点(经纬度)进行比较。 在 for 循环中它可以工作:
for (i in 1:nrow(locations)) {
loc <- locations[i,]
dist <- gdist(-159.5801, 21.901, loc$location_lon, loc$location_lat, units="m")
if(dist <= 50) {
return (loc)
}
return (NULL)
}
然后返回:
id location_lon location_lat
1:11 -159.58 21.901
但我想使用 apply。 以下代码运行失败:
dists <- apply(locations,1,function(x) if (50 - gdist(-159.5801, 21.901, x$location_lon, x$location_lat, units="m")>=0) x else NULL)
出现$ operator is invalid for atomic vectors 错误。更改为按位置引用 (x[2],x[3]) 不足以解决此问题,我明白了
Error in if (radius - gdist(lon, lat, x[2], x[3], units = "m") >= 0) x else NULL :
missing value where TRUE/FALSE needed
这是因为 data.table 转换为矩阵,坐标被视为文本而不是数字。 有没有办法克服这个问题?解决方案需要高效(我想对 >1,000,000 个不同的坐标运行此检查)。如果需要,可以更改位置表的数据结构。
【问题讨论】:
-
我添加了一个工作代码示例。在真正的循环中,所有内容都作为变量传递,并自动生成行名。
-
gdist函数从何而来? -
你能创建一个多行的数据集并提供你想要的输出吗?如果您所做的只是
for循环和apply循环而不使用任何内置的data.table功能,我也看不出使用data.table的任何理由 -
dist来自Imap包 -
不知道这个包。
gdist是矢量化的吗?如果是这样,您不需要任何循环。如果没有,请使用geosphere中的任何dist*函数。
标签: r dataframe data.table