Error when converting latitude and longitude from degrees, minutes and seconds to decimal degrees using measurements package

混江龙づ霸主 提交于 2019-12-12 04:17:13

问题


Short version: I have a dataframe with two columns: Latitude and Longitude, being each of them in degrees, minutes and seconds. After reading some similar questions like this one, I decided to use measurements package to make the conversion, but results get messed when converting from one unit to another (see below).

Detailed version:

Provided the following dataframe where I have two columns, Latitude and Longitude expressed in degrees, minutes and seconds

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\""))

I want to convert those values into decimal degrees by using measurements package as follows:

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")

However, I get the following output:

> 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

As you can see, first row calculated fields seem to be right, whereas starting with line 3, results get messed up, and, hence, being completely useless.

I have read ?conv_unit several times and I don't find any mistake. What am I doing wrong?


回答1:


conv_unit apparently breaks when NA present, presumably because of the way it parses using unlist(strsplit(... as in this line of the source code

secs = lapply(split(as.numeric(unlist(strsplit(x, 
                " "))) * c(3600, 60, 1), f = rep(1:length(x), 
                each = 3)), sum)

So I think you need to ignore NA when you convert, like this:

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")

which gives

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


来源:https://stackoverflow.com/questions/45286995/error-when-converting-latitude-and-longitude-from-degrees-minutes-and-seconds-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!