循环遍历带有条件的data.table行

时间:2015-01-08 09:13:02

标签: r dataframe data.table

我有一个包含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")

然后我想迭代行并将它们与另一个点(使用lat,lon)进行比较。 在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

但我想使用申请。 以下代码无法运行:

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个不同的坐标运行此检查)。如果需要,可以更改位置表的数据结构。

1 个答案:

答案 0 :(得分:4)

不需要循环,只需按预期使用data.table即可。如果您想要查看的是距离所需位置50米范围内的行,您只需要

locations[, if (gdist(-159.58, 21.901, location_lon, location_lat, units="m") <= 50) .SD, id]
##    id location_lon location_lat
## 1: 11      -159.58       21.901

此处,我们按id数据集本身中的locations列进行迭代,并检查每个id是否距离-159.58, 21.901不到50米。如果是这样,我们会调用.SD,这基本上就是特定id的数据集本身。


作为旁注,data.table没有row.names,因此无需指定它们,例如here,请参阅

相关问题