I have a dataframe with columns A and B listing coordinates, but they are in DMS format. I wonder if there is a simple way to convert them into Latitudes and Longitudes format with a R package.
Here is a sample of my database:
structure(list(Nom = c("Pont de Normandie", "Pont de Tancarville",
"Pont de Saint-Nazaire", "Pont de l’Iroise", "Pont d'Aquitaine",
"Viaduc de Millau", "Pont de Brotonne", "Viaduc du Chavanon",
"Pont de Térénez", "Pont du Bras de la Plaine"), Portée = c("856",
"608", "404", "400", "394", "342 (×6)", "320", "300", "285",
"281"), Long. = c(2141, 1420, 3356, 800, 1767, 2460, 1278, 360,
515, 305), Type = c("Haubané\nacier, béton précontraint",
"Suspendu\nacier, béton précontraint, béton armé", "Haubané\nacier, béton précontraint",
"Haubané\nacier, béton précontraint", "Suspendu\nacier, béton précontraint, pylônes en béton armé",
"Haubané\nMultihaubané, 7 piles béton, tablier et pylônes caissons acier, suspension axiale",
"Haubané\nTablier caisson béton, pylônes béton, suspension axiale",
"Suspendu\nTablier caisson mixte acier/béton, pylônes béton, suspension axiale",
"Haubané\nTablier courbe dalle béton, pylônes béton", "Treillis mixte acier/béton, précontrainte extérieure"
), `Voie portée
Voie franchie` = c("Autoroute A29\nRoute européenne 44\nSeine",
"Autoroute A131\nRoute européenne 5\nN182\nSeine", "RD 213\nLoire",
"RN 165\nRoute européenne 60\nÉlorn", "Autoroute A630\nRoute européenne 5\nRocade de Bordeaux\nGaronne",
"Autoroute A75\nRoute européenne 11\nGorges du Tarn", "RD 490\nSeine",
"Autoroute A89\nRoute européenne 70\nChavanon", "RD 791\nAulne",
"RD 26\nBras de la Plaine"), Date = c("1995", "1959", "1975",
"1994", "1967", "2004", "1977", "2000", "2011", "2001"), Localisation = c("Le Havre - Honfleur\n",
"Tancarville - Marais-Vernier\n", "Saint-Nazaire - Saint-Brevin-les-Pins\n",
"Plougastel-Daoulas - Le Relecq-Kerhuon\n", "Bordeaux\n", "Millau - Creissels\n",
"Caudebec-en-Caux\n", "Merlines - Messeix\n", "Landévennec - Rosnoën\n",
"Saint-Pierre - Entre-Deux\n"), A = c("49° 25′ 56,1″ N",
"49° 28′ 21,6″ N", "47° 17′ 06,3″ N", "48° 23′ 18,1″ N",
"44° 52′ 47,2″ N", "44° 04′ 48″ N", "49° 31′ 13,9″ N",
"45° 37′ 26,5″ N", "48° 16′ 07,9″ N", "21° 16′ 35,5″ S"
), B = c("0° 16′ 26,3″ E", "0° 27′ 52,8″ E",
"2° 10′ 13,8″ O", "4° 23′ 55,6″ O", "0° 32′ 09,7″ O",
"3° 01′ 20,6″ E", "0° 44′ 49,8″ E", "2° 28′ 47,5″ E",
"4° 15′ 48,2″ O", "55° 27′ 56,7″ E"), Département = c("Seine-Maritime\nCalvados",
"Seine-Maritime\nEure", "Loire-Atlantique", "Finistère", "Gironde",
"Aveyron", "Seine-Maritime", "Corrèze\nPuy-de-Dôme", "Finistère",
"La Réunion")), row.names = c(NA, -10L), class = c("tbl_df",
"tbl", "data.frame"))
CodePudding user response:
You don't really need a package for this. A simple function should do the trick:
dms_to_degrees <- function(dms) {
sapply(strsplit(dms, "(° )|(' )|(″ )"), function(x) {
sum(as.numeric(gsub(",", ".", x)[1:3]) * c(1, 1/60, 1/3600)) *
c(1, -1, 1, -1)[match(x[4], c("N", "S", "E", "O"))]
})
}
Which allows:
dms_to_degrees(df$A)
#> [1] 49.43225 49.47267 47.28508 48.38836 44.87978 44.08000
#> [7] 49.52053 45.62403 48.26886 -21.27653
dms_to_degrees(df$B)
#> [1] 0.2739722 0.4646667 -2.1705000 -4.3987778 -0.5360278 3.0223889
#> [7] 0.7471667 2.4798611 -4.2633889 55.4657500
And we can confirm this by drawing a map:
library(ggplot2)
ggplot(data = map_data("world"))
geom_map(map = map_data("world"), aes(long, lat, map_id = region),
fill = "#d0e890", color = "gray50")
geom_point(data = within(df, {lat <- dms_to_degrees(A);
long <- dms_to_degrees(B)}),
aes(x = long, y = lat), color = 'red')