2016-10-13 13 views
1

2つのデータフレームの値の間で評価を行い、その結果で新しいデータフレームを作成しようとしています。私はRのパワーには新しく、古いコーディング習慣を避けようとしています。言い換えれば、私は必然的にループの使用を避けようとしていますが、この場合はplyrなどは分かりません。Rでは、2つのデータフレーム間の関数を評価します

サンプルでは、​​空港、パイロット、距離をキロメートル単位で取得する関数を作成しました。私の問題は、各パイロットがどちらの空港に最も近い主要空港と各空港からの距離かを調べることです。

#Build Airports 
code <- c("IAH", "DFW", "Denver", "STL") 
lat <- c(29.97, 32.90, 39.75, 38.75) 
long <- c(95.35, 97.03, 104.87, 90.37) 
airports <- data.frame(code, lat, long) 

#Build Pilots 
names <- c("James", "Fiona", "Seamus") 
lat <- c(32.335131, 44.913223, 28.849631) 
long <- c(-84.989067, -97.151334, -96.917240) 
pilots <- data.frame(names, lat, long) 

#Create distance function 
distInKm <- function(lat1, long1, lat2, long2) { 
    dlat = (lat2 * 0.01745329) - (lat1 * 0.01745329) #pi/180 convert to radians 
    dlong = (long2 * 0.01745329) - (long1 * 0.01745329) 
    step1 = (sin(dlat/2))^2 + cos(lat1 * 0.01745329) * cos(long2 * 0.01745329) * (sin(dlong/2))^2 
    step2 = 2 * atan2(sqrt(step1), sqrt(1 - step1)) 
    dist = 6372.798 * step2 #R is the radius of earth (40041.47/(2 * pi)) 
    dist 
} 

お時間をいただきありがとうございます。

答えて

3

まず、あなたの空港の経度は、負でなければならないときにはプラスになり、結果が失われます。結果は、より多くの意味を作るそれでは、それらを修正してみましょう:

airports$long <- -airports$long 

さて、あなたは各空港のすべてのパイロットを評価するapplyを使用することができます。 geosphereパッケージには、distGeodistHaversineを含む直線距離を計算する関数がいくつかあります。

library(geosphere) 

pilots$closest_airport <- apply(pilots[, 3:2], 1, function(x){ 
    airports[which.min(distGeo(x, airports[, 3:2])), 'code'] 
}) 

pilots$airport_distance <- apply(pilots[, 3:2], 1, function(x){ 
    min(distGeo(x, airports[, 3:2]))/1000 # /1000 to convert m to km 
}) 

pilots 
## names  lat  long closest_airport airport_distance 
## 1 James 32.33513 -84.98907    STL   862.5394 
## 2 Fiona 44.91322 -97.15133   Denver   855.8088 
## 3 Seamus 28.84963 -96.91724    IAH   196.3559 

またはあなたがすべての距離だけではなく、最低1、apply起因するcbind行列たい場合:

dplyrに翻訳
pilots <- cbind(pilots, t(apply(pilots[, 3:2], 1, function(x){ 
    setNames(distGeo(x, airports[, 3:2])/1000, airports$code) 
}))) 

pilots 
## names  lat  long closest_airport  IAH  DFW Denver  STL 
## 1 James 32.33513 -84.98907    STL 1021.6523 1131.2129 1965.6586 862.5394 
## 2 Fiona 44.91322 -97.15133   Denver 1666.0359 1333.6842 855.8088 885.8480 
## 3 Seamus 28.84963 -96.91724    IAH 196.3559 449.1838 1412.0664 1253.4874 

plyr

の後継を
library(dplyr) 

pilots %>% rowwise() %>% 
     mutate(closest_airport = airports[which.min(distGeo(c(long, lat), airports[, 3:2])), 'code'], 
       airport_distance = min(distGeo(c(long, lat), airports[, 3:2]))/1000) 

## Source: local data frame [3 x 5] 
## Groups: <by row> 
## 
## # A tibble: 3 × 5 
## names  lat  long closest_airport airport_distance 
## <fctr> <dbl>  <dbl>   <fctr>   <dbl> 
## 1 James 32.33513 -84.98907    STL   862.5394 
## 2 Fiona 44.91322 -97.15133   Denver   855.8088 
## 3 Seamus 28.84963 -96.91724    IAH   196.3559 

またはすべての距離については、0123を使用してください上記のアプローチと、またはunnestリスト列と再構築:

library(tidyverse) 

pilots %>% rowwise() %>% 
    mutate(closest_airport = airports[which.min(distGeo(c(long, lat), airports[, 3:2])), 'code'], 
      data = list(data_frame(airport = airports$code, 
            distance = distGeo(c(long, lat), airports[, 3:2])/1000))) %>% 
    unnest() %>% 
    spread(airport, distance) 

## # A tibble: 3 × 8 
## names  lat  long closest_airport Denver  DFW  IAH  STL 
## * <fctr> <dbl>  <dbl>   <fctr>  <dbl>  <dbl>  <dbl>  <dbl> 
## 1 Fiona 44.91322 -97.15133   Denver 855.8088 1333.6842 1666.0359 885.8480 
## 2 James 32.33513 -84.98907    STL 1965.6586 1131.2129 1021.6523 862.5394 
## 3 Seamus 28.84963 -96.91724    IAH 1412.0664 449.1838 196.3559 1253.4874 

以上の直接的あまり読みやすくし、

pilots %>% rowwise() %>% 
    mutate(closest_airport = airports[which.min(distGeo(c(long, lat), airports[, 3:2])), 'code'], 
      data = (distGeo(c(long, lat), airports[, 3:2])/1000) %>% 
        setNames(airports$code) %>% t() %>% as_data_frame() %>% list()) %>% 
    unnest() 

## # A tibble: 3 × 8 
## names  lat  long closest_airport  IAH  DFW Denver  STL 
## <fctr> <dbl>  <dbl>   <fctr>  <dbl>  <dbl>  <dbl>  <dbl> 
## 1 James 32.33513 -84.98907    STL 1021.6523 1131.2129 1965.6586 862.5394 
## 2 Fiona 44.91322 -97.15133   Denver 1666.0359 1333.6842 855.8088 885.8480 
## 3 Seamus 28.84963 -96.91724    IAH 196.3559 449.1838 1412.0664 1253.4874 
+0

OPは、それぞれのパイロットがあるパイロット最寄りのではない主要などの空港を決定しようとしています各空港に最も近い – HubertL

+0

@HubertLUops、それを後方に読んでください。一定。 – alistaire

+0

あなたはそれを後ろに読んでいるので、それは後ろに書かれています。 – HubertL

関連する問題