Применить пользовательскую функцию к каждой строке в dataframe

#r #dplyr

#r #dplyr

Вопрос:

Я пытаюсь применить пользовательскую функцию, которую я написал, к фрейму данных, чтобы определить ближайший аэропорт с учетом широты и долготы. Вот процесс и код ниже:

  1. Фрейм данных состоит из города, штата, страны, широты, длины
  2. Пользовательская функция использует airportr пакет для определения ближайшего аэропорта, используя широту и длину в качестве входных данных функции
  3. Выводом будет название города и код аэропорта IATA.
  4. Конечным результатом будет фрейм данных с кодами городов и аэропортов.

Когда я запускаю ее с помощью apply , я получаю следующую ошибку:

Error in lat * pi : non-numeric argument to binary operator

Это заставляет меня думать apply , что неправильно извлекает данные. Вот код и reprex:

 library(tidyverse)
library(airportr)

locations <- tribble(~city, ~lat, ~long,

  
locations <- tribble(~city, ~lat, ~long,
                      "Philadelphia", 40.01, -75.1,
                      "Denver", 39.77, -104.87,
                      "Atlanta", 33.76, -84.42)

nearby <- function(x, output) {
  # access primary variables
  city = x[1]
  lat = x[2]
  long = x[3]
  # calculate closest airport
  airport <- airports_around(lat, long, distance=50) %>%
    select(Name, IATA, Latitude, Longitude) %>%
    # renove useless IATA codes
    filter(IATA != "\N") %>%
    #calculates minmimum distance difference - probably a better way to do this
        mutate(lat_diff = Latitude-lat,
           long_diff = Longitude-long,
           sum = lat_diff long_diff) %>%
    slice(which.min(sum)) %>%
    pull(IATA)
  #puts back together into a dataframe
  data.frame(city, airport)
}



#apply function
apply(locations, 1, nearby) -> tmp

#reform to a dataframe
data.frame(matrix(unlist(tmp), nrow=length(tmp), byrow=T))



#apply function
apply(locations %>% slice(1:10), 1, nearby) -> tmp

#reform to a dataframe
data.frame(matrix(unlist(tmp), nrow=length(tmp), byrow=T))
 

Обновить
Основываясь на комментарии от thelatemail, я смог заставить его работать, сначала преобразовав столбцы в числовые:

 nearby <- function(x, output) {
  # access primary variables
  city = x[1]
  lat = x[2] %>% as.numeric()
  long = x[3] %>% as.numeric()
  # calculate closest airport
  airport <- airports_around(lat, long, distance=50) %>%
    select(Name, IATA, Latitude, Longitude) %>%
    # renove useless IATA codes
    filter(IATA != "\N") %>%
    #calculates minmimum distance difference - probably a better way to do this
        mutate(lat_diff = Latitude-lat,
           long_diff = Longitude-long,
           sum = lat_diff long_diff) %>%
    slice(which.min(sum)) %>%
    pull(IATA)
  #puts back together into a dataframe
  data.frame(city, airport)
}
 

Комментарии:

1.Не уверен, как решить эту точную проблему в мире dplyr, но проблема в том, что apply весь набор данных преобразуется в matrix первый, что означает, что все ваши числа становятся строками. Затем это приведет к ошибке, когда вы попытаетесь выполнить какие-либо арифметические действия в каждой строке.

2. Что ж, эти знания позволили мне исправить мою функцию, добавляя %>% as.numeric() после каждого вызова индекса в функции!