我试图将一组40个坐标从度数十进制分钟格式转换为纬度和经度的十进制度数格式。我在这里包含了一些坐标,它们是我现有的格式:
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
保持行顺序很重要,这样我就可以将这些列绑定回原始数据框架。由于这个原因,我不想删除空白条目的行。
到目前为止,我已经尝试应用测量包中的conv_unit函数,这将起作用,但只有到第19行才能转换纬度坐标。然后,它将产生警告消息"数据长度不是split变量的倍数",我认为这解释了为什么转换在第19行之后停止(尽管我不确定)。经度坐标根本无法转换,我将收到以下错误消息:"错误:'conv_units'不是从'namespace:measurements'导出的对象。"我试图避免手工进行转换以减少计算错误,因此希望找到一个函数来帮助我。似乎测量包是票,但我似乎无法解决这些问题。
我怎么能把我所有的纬度/长坐标转换成十进制度数格式从他们当前的度数十进制分钟格式?
您可以很容易地做到这一点,因为R是矢量化的。只需用sapply
中的一个小函数将相关子串除以60。
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
数据:
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"))
我找到了一个很棒的包解析器(https://github.com/ropensci/parzer),它可以解决所有这些问题
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:
测量包可以工作,但是它要求您将输入坐标修改为特定的格式(即,用空格分隔单位)。包最初不能为我工作的原因是因为我没有以正确的格式输入!
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