У меня есть работающая функция mapply — как преобразовать ее в mlply?

Я написал следующий код R, который выделяет ближайший почтовый индекс к набору северных/восточных координат:

# Set of northing / easting coordinates that I need to assign a postcode to
x1 <- c(1,2,4,6,7)
y1 <- c(5,2,4,7,8)

# Postcode with northing / easting coordinates
postcode <- c("Postcode A", "Postcode B", "Postcode C", "Postcode D")
x2 <- c(5,3,4,2)
y2 <- c(8,1,2,4)

# Function that attributes closest postcode to (x1, y1) coordinates
algo <- function(x, y)
{
        dist <- which.min(sqrt(((x2 - x)^2) + ((y2 - y)^2)))
}

# mapply to run the function, and find the closest coordinates
postcode[mapply(algo, x1, y1, SIMPLIFY = T)]
[1] "Postcode D" "Postcode B" "Postcode C" "Postcode A" "Postcode A"

Поскольку у меня более 500 000 (x1, y1) координат и более 1 000 000 (x2, y2) координат, эта функция отображения занимает много времени, и я хочу следить за ходом выполнения. Я понимаю, что у mlply есть функция индикатора выполнения, но я не могу заставить ее работать. Что я сделал:

# Using mlply to run the function, and find the closest coordinates with progress bar
library(plyr)
postcode[mlply(cbind(x1, y1), .fun = algo, .progress = "tk")]

Что я делаю не так? Был бы признателен за правильный код R для mlply (или других функций m * ply) и объяснение того, почему вышеизложенное неверно.

Большое спасибо за ваше время и внимание.


person dannychan0510    schedule 30.03.2016    source источник


Ответы (1)


Я заметил как минимум две проблемы.

Во-первых, имена ваших столбцов во фрейме данных не совпадают с именами аргументов в вашей функции. Следующий код работает без предупреждения.

mlply(cbind(x= x1, y =y1), .fun = algo, .progress = "tk")

Во-вторых, mlply возвращает список с элементами, которые нельзя использовать для подмножества вашего вектора почтового индекса:

mlply(.data = cbind(x = x1, y = y1), .fun = algo, .progress = "tk")

$1 [1] 4

$2 [1] 2

$3 [1] 3

$4 [1] 1

$5 [1] 1

attr(,"split_type") [1] "массив" attr(,"split_labels") x y 1 1 5 2 2 2 3 4 4 4 6 7 5 7 8

Для решения предлагаю:

postcode[unlist(mlply(.data = cbind(x = x1, y = y1), 
    .fun = algo, .progress = "tk"))[1:length(x1)]]

И последнее. Если вы пытаетесь найти минимальное расстояние, вы можете рассмотреть возможность прямого поиска минимального квадрата расстояния (вы избегаете вычисления квадратного корня миллион раз, что должно улучшить время).

person DeveauP    schedule 30.03.2016