如何在R中将度分秒转换为十进制?

6

I have this dataframe:

Lat        Long
59 44 50   151 45 11
59 49 28   154 52 56
59 46 42   150 45 15

如何将这个转换为十进制列?

纬度是以dd mm ss格式,经度是以ddd mm ss格式。

我在这里找到了一个类似的解决方案,但无法适应我的情况。

将地理坐标从度转换为十进制

3个回答

14

试试这个函数:

angle2dec <- function(angle) {
  angle <- as.character(angle)
  x <- do.call(rbind, strsplit(angle, split=' '))
  x <- apply(x, 1L, function(y) {
    y <- as.numeric(y)
    y[1] + y[2]/60 + y[3]/3600
  })
  return(x)
}

然后你可以将它应用于数据框中的每一列:

new_df <- apply(df, 2L, angle2dec)
new_df
          Lat     Long
[1,] 59.74722 151.7531
[2,] 59.82444 154.8822
[3,] 59.77833 150.7542

或者仅仅是

df$Lat <- angle2dec(df$Lat)
df$Long <- angle2dec(df$Long)

我得到了这个错误:在strsplit(angle, split = " ")中的非字符参数。 - maximusdooku
哦,我以为你的列的类别是“字符”。它是因子吗?无论如何,请尝试我所做的编辑。 - Bridgeburners
这是经度/纬度的因子。还有其他列,但我现在没有对它们进行操作。 - maximusdooku
我似乎无法重现你的错误。你是如何执行这个函数的? - Bridgeburners
1
经度有不同的约定。有些使用0到360之间的值,有些使用-180到180之间的值。您的数据框架的约定没有指定,但无论是哪种约定,我给出的转换应该是从分钟和秒转换为十进制的正确方法。您可以尝试将结果进行适当的转换。(例如,如果您使用的地图使用-180到180的约定,请尝试Long - 180。) - Bridgeburners
显示剩余5条评论

4
我建议使用 tidyr 的方法:

df <- data.frame( Lat=c("59 44 50","59 49 28","59 46 42"),
                 Long=c("151 45 11","154 52 56","150 45 15"))

library(tidyr); library(dplyr)
df %>% 
  separate(Lat, paste("lat",c("d","m","s"), sep="_") ) %>%
  separate(Long, paste("long",c("d","m","s"), sep="_" ) ) %>%
  mutate_each(funs(as.numeric)) %>%
  transmute(lat_dec=lat_d + lat_m/60 + lat_s/60^2,
            long_dec=long_d + long_m/60 + long_s/60^2)

#    lat_dec long_dec
# 1 59.74722 151.7531
# 2 59.82444 154.8822
# 3 59.77833 150.7542

这是在R中比其他答案中的strsplit方法更受欢迎的方法吗?只是好奇。 - maximusdooku
编写函数可能是更好的方法,因为您只需编写一次,就可以使用两次。我本来想用strsplit,但其他人比我先完成了。 - C8H10N4O2
1
非常欢迎。我认为 Bridgeburners 展示了一些基本的工具(do.call、rbind、apply),一旦你学会了这些,那么 dplyr 和 tidyr 包绝对值得一试。 - C8H10N4O2

3
这里有一个使用splitstackshape的想法:
library(dplyr)
library(splitstackshape)

df %>% 
  cSplit(c("Lat", "Long"), sep = " ") %>%
  transmute(Lat = Lat_1 + Lat_2 / 60 + Lat_3 / 60^2,
            Long = Long_1 + Long_2 / 60 + Long_3 / 60^2)

这将会给出:

#        Lat     Long
#1: 59.74722 151.7531
#2: 59.82444 154.8822
#3: 59.77833 150.7542

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接