使用测量包将纬度和经度从度、分和秒转换为十进制度时出错
Error when converting latitude and longitude from degrees, minutes and seconds to decimal degrees using measurements package
简短版本: 我有一个包含两列的数据框:纬度和经度,每一列都以度、分和秒为单位。在阅读了一些类似的问题 like this one 后,我决定使用 measurements
包进行转换,但是当从一个单位转换为另一个单位时,结果变得一团糟(见下文)。
详细版:
提供了以下数据框,其中我有两列,Latitude
和 Longitude
,以度、分和秒表示
df = data.frame(
Latitude = c("15° 33' 9\"",NA,"52° 58' 13\"", NA, "21° 1' 28\"", "21° 2' 26\"", "10° 47' 31\"", NA, "-34° 53' 38\"", "41° 7' 56\""),
Longitude = c("48° 30' 59\"", NA, "-3° 10' 13\"", NA, "105° 50' 34\"", "105° 47' 52\"", "106° 41' 29\"", NA, "-56° 8' 16\"", "-104° 46' 30\""))
我想使用 measurements
包将这些值转换为十进制度数,如下所示:
library(measurements)
# Turn degrees, minutes and seconds into spaces so they can be used with
# measurements::conv_unit.
df$Latitude = str_replace(df$Latitude, "°", "")
df$Latitude = str_replace(df$Latitude, "'", "")
df$Latitude = str_replace(df$Latitude, "\"", "")
df$Longitude = str_replace(df$Longitude, "°", "")
df$Longitude = str_replace(df$Longitude, "'", "")
df$Longitude = str_replace(df$Longitude, "\"", "")
# Use measurements::conv_unit to convert to decimal degrees.
df$Latitude = conv_unit(df$Latitude, "deg_min_sec", "dec_deg")
df$Longitude = conv_unit(df$Longitude, "deg_min_sec", "dec_deg")
但是,我得到以下输出:
> df
Latitude Longitude Latitude_dec Longitude_dec
1 15° 33' 9" 48° 30' 59" 15.5525 48.5163888888889
2 <NA> <NA> <NA> <NA>
3 52° 58' 13" -3° 10' 13" <NA> <NA>
4 <NA> <NA> 1.4725 50.5958333333333
5 21° 1' 28" 105° 50' 34" 2.43611111111111 47.8961111111111
6 21° 2' 26" 105° 47' 52" <NA> <NA>
7 10° 47' 31" 106° 41' 29" 34.8938888888889 56.1377777777778
8 <NA> <NA> 41.1322222222222 104.775
9 -34° 53' 38" -56° 8' 16" -0 -0
10 41° 7' 56" -104° 46' 30" 0 -0
如您所见,第一行计算字段似乎是正确的,而从第 3 行开始,结果变得混乱,因此完全没有用。
我看了?conv_unit
好几遍,没有发现任何错误。我做错了什么?
conv_unit
显然在 NA 出现时中断,大概是因为它使用 unlist(strsplit(...
进行解析的方式,如源代码的这一行
secs = lapply(split(as.numeric(unlist(strsplit(x,
" "))) * c(3600, 60, 1), f = rep(1:length(x),
each = 3)), sum)
所以我认为你需要在转换时忽略NA
,像这样:
library(measurements)
df = data.frame(
Latitude = c("15° 33' 9\"",NA,"52° 58' 13\"", NA, "21° 1' 28\"", "21° 2' 26\"", "10° 47' 31\"", NA, "-34° 53' 38\"", "41° 7' 56\""),
Longitude = c("48° 30' 59\"", NA, "-3° 10' 13\"", NA, "105° 50' 34\"", "105° 47' 52\"", "106° 41' 29\"", NA, "-56° 8' 16\"", "-104° 46' 30\""))
# Turn degrees, minutes and seconds into spaces so they can be used with
# measurements::conv_unit.
# NOTE THIS CAN BE DONE IN ONE OR TWO LINES USING REGEX "OR" (|)
# - I would think this could be done in stringr::str_replace too
# - but I don't know how.
df$Latitude = gsub("°|'|\"", "", df$Latitude)
df$Longitude = gsub("°|'|\"", "", df$Longitude)
# Use measurements::conv_unit to convert to decimal degrees.
not_na <- !is.na(df$Latitude) #identify non-na (I assume same for Long here)
#convert only non-na values
df$Latitude[not_na] = conv_unit(df$Latitude[not_na], "deg_min_sec", "dec_deg")
df$Longitude[not_na] = conv_unit(df$Longitude[not_na], "deg_min_sec", "dec_deg")
这给出了
df
Latitude Longitude
1 15.5525 48.5163888888889
2 <NA> <NA>
3 52.9702777777778 -3.17027777777778
4 <NA> <NA>
5 21.0244444444444 105.842777777778
6 21.0405555555556 105.797777777778
7 10.7919444444444 106.691388888889
8 <NA> <NA>
9 -34.8938888888889 -56.1377777777778
10 41.1322222222222 -104.775
简短版本: 我有一个包含两列的数据框:纬度和经度,每一列都以度、分和秒为单位。在阅读了一些类似的问题 like this one 后,我决定使用 measurements
包进行转换,但是当从一个单位转换为另一个单位时,结果变得一团糟(见下文)。
详细版:
提供了以下数据框,其中我有两列,Latitude
和 Longitude
,以度、分和秒表示
df = data.frame(
Latitude = c("15° 33' 9\"",NA,"52° 58' 13\"", NA, "21° 1' 28\"", "21° 2' 26\"", "10° 47' 31\"", NA, "-34° 53' 38\"", "41° 7' 56\""),
Longitude = c("48° 30' 59\"", NA, "-3° 10' 13\"", NA, "105° 50' 34\"", "105° 47' 52\"", "106° 41' 29\"", NA, "-56° 8' 16\"", "-104° 46' 30\""))
我想使用 measurements
包将这些值转换为十进制度数,如下所示:
library(measurements)
# Turn degrees, minutes and seconds into spaces so they can be used with
# measurements::conv_unit.
df$Latitude = str_replace(df$Latitude, "°", "")
df$Latitude = str_replace(df$Latitude, "'", "")
df$Latitude = str_replace(df$Latitude, "\"", "")
df$Longitude = str_replace(df$Longitude, "°", "")
df$Longitude = str_replace(df$Longitude, "'", "")
df$Longitude = str_replace(df$Longitude, "\"", "")
# Use measurements::conv_unit to convert to decimal degrees.
df$Latitude = conv_unit(df$Latitude, "deg_min_sec", "dec_deg")
df$Longitude = conv_unit(df$Longitude, "deg_min_sec", "dec_deg")
但是,我得到以下输出:
> df
Latitude Longitude Latitude_dec Longitude_dec
1 15° 33' 9" 48° 30' 59" 15.5525 48.5163888888889
2 <NA> <NA> <NA> <NA>
3 52° 58' 13" -3° 10' 13" <NA> <NA>
4 <NA> <NA> 1.4725 50.5958333333333
5 21° 1' 28" 105° 50' 34" 2.43611111111111 47.8961111111111
6 21° 2' 26" 105° 47' 52" <NA> <NA>
7 10° 47' 31" 106° 41' 29" 34.8938888888889 56.1377777777778
8 <NA> <NA> 41.1322222222222 104.775
9 -34° 53' 38" -56° 8' 16" -0 -0
10 41° 7' 56" -104° 46' 30" 0 -0
如您所见,第一行计算字段似乎是正确的,而从第 3 行开始,结果变得混乱,因此完全没有用。
我看了?conv_unit
好几遍,没有发现任何错误。我做错了什么?
conv_unit
显然在 NA 出现时中断,大概是因为它使用 unlist(strsplit(...
进行解析的方式,如源代码的这一行
secs = lapply(split(as.numeric(unlist(strsplit(x,
" "))) * c(3600, 60, 1), f = rep(1:length(x),
each = 3)), sum)
所以我认为你需要在转换时忽略NA
,像这样:
library(measurements)
df = data.frame(
Latitude = c("15° 33' 9\"",NA,"52° 58' 13\"", NA, "21° 1' 28\"", "21° 2' 26\"", "10° 47' 31\"", NA, "-34° 53' 38\"", "41° 7' 56\""),
Longitude = c("48° 30' 59\"", NA, "-3° 10' 13\"", NA, "105° 50' 34\"", "105° 47' 52\"", "106° 41' 29\"", NA, "-56° 8' 16\"", "-104° 46' 30\""))
# Turn degrees, minutes and seconds into spaces so they can be used with
# measurements::conv_unit.
# NOTE THIS CAN BE DONE IN ONE OR TWO LINES USING REGEX "OR" (|)
# - I would think this could be done in stringr::str_replace too
# - but I don't know how.
df$Latitude = gsub("°|'|\"", "", df$Latitude)
df$Longitude = gsub("°|'|\"", "", df$Longitude)
# Use measurements::conv_unit to convert to decimal degrees.
not_na <- !is.na(df$Latitude) #identify non-na (I assume same for Long here)
#convert only non-na values
df$Latitude[not_na] = conv_unit(df$Latitude[not_na], "deg_min_sec", "dec_deg")
df$Longitude[not_na] = conv_unit(df$Longitude[not_na], "deg_min_sec", "dec_deg")
这给出了
df Latitude Longitude 1 15.5525 48.5163888888889 2 <NA> <NA> 3 52.9702777777778 -3.17027777777778 4 <NA> <NA> 5 21.0244444444444 105.842777777778 6 21.0405555555556 105.797777777778 7 10.7919444444444 106.691388888889 8 <NA> <NA> 9 -34.8938888888889 -56.1377777777778 10 41.1322222222222 -104.775