2016-11-11 16 views
5

Nie mogę rozwiązać błędu: "zła długość dla wektora powinna wynosić 2" przy próbie obliczenia odległości (drogi startowej) między dwoma punktami (progi/końce drogi startowej). Na domiar złego, nie rozumiem odpowiedzi, takich jak tutaj R error: Wrong length for a vector, should be 2 i zastosować je do mojej sprawy. Uproszczony ramki danych (koniec drogi startowej) pozycji wygląda następująco:geosphere distHaversine() i dplyr - błąd nieprawidłowej długości dla wektora powinien być 2

runways <- data.frame(
RWY_ID = c(1,2,3) 
,RWY = c("36R", "36L","01") 
,LAT = c(40.08, 40.12, 40.06) 
,LON = c(116.59, 116.57, 116.62) 
,LAT2 = c(40.05, 40.07,40.09) 
,LON2 = c(116.6, 116.57, 116.61) 
) 

Korzystanie z funkcji distHaversine() z geosfery, staram się obliczyć odległość:

runways <- mutate(runways 
       , CTD = distHaversine(c(LON, LAT), c(LON2, LAT2)) 
       ) 

Nie jestem pewien, co Robię źle tutaj. Jeśli wyciągnę pozycję LON LAT, jest to wektor liczbowy o odpowiedniej długości.

myv <- c(runways$LON[1], runways$LAT[1]) 
myv 

[1] 116.59 40.08 
str(myv) 
num [1:2] 116.6 40.1 
+2

Musisz działać "rowwise", lub przechodzisz wszystkie wiersze naraz: 'runways%>% rowwise()%>% mutate (CTD = geosphere :: distHaversine (c (LON, LAT), c (LON2, LAT2))) ' – alistaire

+1

DZIĘKI !!! Alistaire ... życie może być takie łatwe. Zakładam, że komunikat o błędzie wskazuje na fakt, że sortowane wektoryzowane podejście przekracza wymaganą długość 2. – Rainer

Odpowiedz

9

Trzeba działać rowwise, więc distHaversine przepuszcza jeden zestaw par na raz zamiast wszystkich wierszy:

runways %>% rowwise() %>% 
    mutate(CTD = distHaversine(c(LON, LAT), c(LON2, LAT2))) 

## Source: local data frame [3 x 7] 
## Groups: <by row> 
## 
## # A tibble: 3 × 7 
## RWY_ID RWY LAT LON LAT2 LON2  CTD 
## <dbl> <fctr> <dbl> <dbl> <dbl> <dbl> <dbl> 
## 1  1 36R 40.08 116.59 40.05 116.60 3446.540 
## 2  2 36L 40.12 116.57 40.07 116.57 5565.975 
## 3  3  01 40.06 116.62 40.09 116.61 3446.509 

Alternatywnie distHaversine może obsługiwać macierze, dzięki czemu można używać cbind zamiast od c:

runways %>% mutate(CTD = distHaversine(cbind(LON, LAT), cbind(LON2, LAT2))) 

## RWY_ID RWY LAT LON LAT2 LON2  CTD 
## 1  1 36R 40.08 116.59 40.05 116.60 3446.540 
## 2  2 36L 40.12 116.57 40.07 116.57 5565.975 
## 3  3 01 40.06 116.62 40.09 116.61 3446.509 

w skali, to ostatnie podejście jest prawie na pewno lepiej, jak woź- w rzucie rzędowym nie wykorzystuje wektoryzacji i dlatego może się spowalniać.

+1

Dzięki, Alistaire, jestem ci winien piwo. Teraz widząc rozwiązanie, czuję się trochę pokorny, gdy pytam. Przejście do macierzy przez cbind() wydaje się nieco bardziej eleganckie niż iteracje wierszowe. Jeszcze dużo przed sobą, aby dowiedzieć się o R ... :) – Rainer

+1

Bez obaw, to dobre pytanie. Myślenie o tym, co przechodzisz do funkcji, kiedy odwołujesz się do nazwy kolumny w dplyr, jest jednym z tych stałych i nieprzekazywanych od razu zadań, aby uniknąć błędów przy wykonywaniu skomplikowanych funkcji. – alistaire

0

Mam coś do dodania. Spędziłem na tym dużo czasu. W końcu dowiedziałem się, że nie powinienem używać tego formularza wewnątrz dplyr. Po wejściu do dplyr należy bezpośrednio wywołać nazwę zmiennej.