2015-01-08 4 views
1

У меня есть таблица данных, содержащая идентификаторы и местоположения. например, вот это с одной строки в нем: (он имеет Col и строк имен, не знаю, если это имеет значение)Петля по таблице данных.table с условием

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 (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 различных координат). При необходимости возможно изменение структуры данных таблицы местоположений.

+0

Я добавил этот пример для рабочего кода. В реальном цикле все передается как переменные, а rowname автоматически генерируется. – KeshetE

+0

Где происходит функция gdist? – nicola

+0

Можете ли вы создать набор данных с несколькими строками и предоставить желаемый результат? Я также не вижу причины использовать 'data.table', если все, что вы делаете, - это циклы' for' и 'apply', без использования встроенных функций' data.table' –

ответ

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 находится в 50 метрах от -159.58, 21.901. Если это так, мы вызываем .SD, который в основном является набором данных для этого конкретного id.


В качестве примечания, data.table не row.names, поэтому нет никакой необходимости specifiying их, см here, например

+1

Спасибо, это очень помогает! – KeshetE

+1

NP, я действительно советую вам прочитать некоторую документацию 'data.table', так как кажется, что вы ее не используете, как предполагалось. На SO есть много хороших ответов на тег [tag: data.table], опубликованный @Arun, что вы можете многому научиться из –

Смежные вопросы