【问题标题】:Error when converting latitude and longitude from degrees, minutes and seconds to decimal degrees using measurements package使用测量包将纬度和经度从度、分和秒转换为十进制度时出错
【发布时间】:2017-12-30 10:01:22
【问题描述】:

简短版:我有一个包含两列的数据框:纬度和经度,分别以度、分和秒为单位。在阅读了一些类似的问题like this one 之后,我决定使用measurements 包进行转换,但是从一个单位转换为另一个单位时结果会变得混乱(见下文)。

详细版本:

提供了以下数据框,其中我有两列,LatitudeLongitude,以度、分和秒表示

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 好几遍了,我没有发现任何错误。我做错了什么?

【问题讨论】:

    标签: r units-of-measurement


    【解决方案1】:

    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
    

    【讨论】:

    • 非常感谢您的解决方案(以及对我的代码的改进)。我猜这与NA有关,但不知道如何获得任何线索,也不知道如何面对它。非常聪明的解决方案!
    猜你喜欢
    • 1970-01-01
    • 2010-11-11
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多