Reputation: 53
I am trying to convert a group of 40 coordinates from degree decimal minute format into decimal degree format for latitude and longitude. I have included some coordinates here that are in my existing format:
lat long
1 49°46.938 76°62.082
2 49°47.957 70°22.089
3 49°48.938 69°07.043
4 49°48.936 79°72.022
5 49°48.950 73°62.060
6 49°46.749 70°92.214
7 49°47.736 73°92.223
8 49°46.707 79°52.232
9 49°47.680 80°32.123
10 49°46.678 79°02.123
11 49°47.678 79°82.123
12 49°96.694 75°32.123
13 49°97.713 70°92.091
14 49°46.555 71°72.143
15 49°47.575 72°32.143
16 49°46.472 79°62.276
17 49°47.689 79°82.664
18 49°46.622 70°22.255
19
20 49°65.681 79°74.632
21 49°46.693 73°08.656
22 49°65.682 72°09.695
23 49°47.645 72°09.703
24 49°42.673 74°55.727
25 49°43.903 73°09.750
26 49°98.762 73°83.754
27 45°43.604 70°92.869
28 49°37.202 78°03.843
29 49°38.287 79°33.709
30 49°94.308 74°44.439
31 49°94.777 79°35.404
32
33 49°37.723 79°87.833
34 49°78.664 79°07.844
35 49°60.877 75°60.855
36 49°03.336 73°22.851
37 49°52.496 88°88.861
38 49°38.940 79°67.871
39 49°96.049 79°54.881
40 49°37.240 78°39.892
Maintaining the row order is important so I can bind these columns back into my original dataframe. For this reason, I don't want to drop the rows of blank entries.
So far I have tried applying the conv_unit function from the measurements package, and that will work but only until row 19 for converting the latitude coordinates. It will then produce the warning message "data length is not a multiple of split variable", which I assume explains why the conversion stops after row 19 (although I'm not sure ). The longitude coordinates won't convert at all, and I will receive the following error message: "Error: 'conv_units' is not an exported object from 'namespace:measurements'."
I am trying to avoid doing the conversions by hand to reduce calculation errors, and so was hoping to find a function to help me. It seems like the measurements package is the ticket, but I can't seem to work through these issues.
How can I convert ALL of my lat/long coordinates into decimal degree format from their current degree decimal minute format?
Upvotes: 3
Views: 2592
Reputation: 51
I found the great package parzer (https://github.com/ropensci/parzer) that solves all these kind of issues
lat = c("49°46.938", "49°47.957", "49°48.938", "49°48.936", "49°48.950", "49°46.749", "49°47.736", "49°46.707", "49°47.680", "49°46.678", "49°47.678", "49°96.694", "49°97.713", "49°46.555", "49°47.575", "49°46.472", "49°47.689", "49°46.622", "", "49°65.681", "49°46.693", "49°65.682", "49°47.645", "49°42.673", "49°43.903", "49°98.762", "45°43.604", "49°37.202", "49°38.287", "49°94.308", "49°94.777", "", "49°37.723", "49°78.664", "49°60.877", "49°03.336", "49°52.496", "49°38.940", "49°96.049", "49°37.240")
long = c("76°62.082", "70°22.089", "69°07.043", "79°72.022", "73°62.060", "70°92.214", "73°92.223", "79°52.232", "80°32.123", "79°02.123", "79°82.123", "75°32.123", "70°92.091", "71°72.143", "72°32.143", "79°62.276", "79°82.664", "70°22.255", "", "79°74.632", "73°08.656", "72°09.695", "72°09.703", "74°55.727", "73°09.750", "73°83.754", "70°92.869", "78°03.843", "79°33.709", "74°44.439", "79°35.404", "", "79°87.833", "79°07.844", "75°60.855", "73°22.851", "88°88.861", "79°67.871", "79°54.881", "78°39.892")
parzer::parse_lon_lat(lon = long, lat = lat)
# lon lat
# 1 77.03470 49.78230
# 2 70.36815 49.79928
# 3 69.11739 49.81563
# 4 80.20036 49.81560
# 5 74.03433 49.81583
# 6 71.53690 49.77915
# 7 74.53705 49.79560
# 8 79.87054 49.77845
# 9 80.53539 49.79467
# 10 79.03539 49.77797
# 11 80.36871 49.79463
# 12 75.53539 50.61157
# 13 71.53485 50.62855
# 14 72.20238 49.77592
# 15 72.53571 49.79292
# 16 80.03793 49.77453
# 17 80.37773 49.79482
# 18 70.37092 49.77703
# 19 NaN NaN
# 20 80.24387 50.09468
# 21 73.14426 49.77822
# 22 72.16158 50.09470
# 23 72.16172 49.79408
# 24 74.92878 49.71122
# 25 73.16250 49.73172
# 26 74.39590 50.64603
# 27 71.54781 45.72673
# 28 78.06405 49.62003
# 29 79.56181 49.63811
# 30 74.74065 50.57180
# 31 79.59007 50.57962
# 32 NaN NaN
# 33 80.46388 49.62872
# 34 79.13073 50.31107
# 35 76.01425 50.01462
# 36 73.38085 49.05560
# 37 89.48102 49.87494
# 38 80.13118 49.64900
# 39 79.91468 50.60081
# 40 78.66486 49.62067
# Warning messages:
# 1: In base::.Call(...) : no digits detected, got:
# 2: In base::.Call(...) : no digits detected, got:
# 3: In base::.Call(...) : no digits detected, got:
# 4: In base::.Call(...) : no digits detected, got:
Upvotes: 4
Reputation: 53
It turns out that the measurements package works, but it requires that you modify the input coordinates into a particular format (i.e., with the units separated by a space). The reason the package wasn't initially working for me is because I didn't have my input in the correct format!
df$column <- measurements::conv_unit(df$column, from = 'deg_dec_min', to = 'dec_deg') # convert lat column from degrees and decimal minutes into decimal degrees
Upvotes: 1
Reputation: 73702
You may do that pretty easily, since R is vectorized. Just divide the relevant substrings by 60 with a small function in an sapply
.
f <- function(x) as.double(substr(x, 1, 2)) + as.double(substring(x, 3)) / 60
sapply(d, f)
# lat long
# [1,] 49.78230 77.03470
# [2,] 49.79928 70.36815
# [3,] 49.81563 69.11738
# [4,] 49.81560 80.20037
# [5,] 49.81583 74.03433
# [6,] 49.77915 71.53690
# [7,] 49.79560 74.53705
# [8,] 49.77845 79.87053
# [9,] 49.79467 80.53538
# [10,] 49.77797 79.03538
# [11,] 49.79463 80.36872
# [12,] 50.61157 75.53538
# [13,] 50.62855 71.53485
# [14,] 49.77592 72.20238
# [15,] 49.79292 72.53572
# [16,] 49.77453 80.03793
# [17,] 49.79482 80.37773
# [18,] 49.77703 70.37092
# [19,] NA NA
# [20,] 50.09468 80.24387
# [21,] 49.77822 73.14427
# [22,] 50.09470 72.16158
# [23,] 49.79408 72.16172
# [24,] 49.71122 74.92878
# [25,] 49.73172 73.16250
# [26,] 50.64603 74.39590
# [27,] 45.72673 71.54782
# [28,] 49.62003 78.06405
# [29,] 49.63812 79.56182
# [30,] 50.57180 74.74065
# [31,] 50.57962 79.59007
# [32,] NA NA
# [33,] 49.62872 80.46388
# [34,] 50.31107 79.13073
# [35,] 50.01462 76.01425
# [36,] 49.05560 73.38085
# [37,] 49.87493 89.48102
# [38,] 49.64900 80.13118
# [39,] 50.60082 79.91468
# [40,] 49.62067 78.66487
Data:
d <- structure(list(lat = c(4946.938, 4947.957, 4948.938, 4948.936,
4948.95, 4946.749, 4947.736, 4946.707, 4947.68, 4946.678, 4947.678,
4996.694, 4997.713, 4946.555, 4947.575, 4946.472, 4947.689, 4946.622,
NA, 4965.681, 4946.693, 4965.682, 4947.645, 4942.673, 4943.903,
4998.762, 4543.604, 4937.202, 4938.287, 4994.308, 4994.777, NA,
4937.723, 4978.664, 4960.877, 4903.336, 4952.496, 4938.94, 4996.049,
4937.24), long = c(7662.082, 7022.089, 6907.043, 7972.022, 7362.06,
7092.214, 7392.223, 7952.232, 8032.123, 7902.123, 7982.123, 7532.123,
7092.091, 7172.143, 7232.143, 7962.276, 7982.664, 7022.255, NA,
7974.632, 7308.656, 7209.695, 7209.703, 7455.727, 7309.75, 7383.754,
7092.869, 7803.843, 7933.709, 7444.439, 7935.404, NA, 7987.833,
7907.844, 7560.855, 7322.851, 8888.861, 7967.871, 7954.881, 7839.892
)), class = "data.frame", row.names = c("1", "2", "3", "4", "5",
"6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
"17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
"28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38",
"39", "40"))
Upvotes: 3