1

I am using the library sp as suggested here and here to convert from degree-minute-second (dms) representation to decimal degrees(dd).

If I try the following code using sp, this is the result:

loc$Lat<-sp::char2dms(loc$Lat)

Error in rep(value, length.out = nrows) : attempt to replicate an object of type 'S4'

A sample of my data is as follows:

    c("39d47m01s N", "15d38m08s N", "12d45m01s N", "13d17m25s N", 
    "36d34m29s N", "24d46m34s S", "11d52m39s S", "39d47m01s N", "30d52m34s N", 
    "34d59m47s S")

I need to convert from dms to dd as I want to calculate Haversine (great circle distances) between points.

I am also open to using other packages to do the conversion.

I tried using the library birk but it is giving me some meaningless answers where the lat/long are greater than 1000. Before, trying birk, I had converted the lat/long representation to one that birk accepts in its conv_unit function

Community
  • 1
  • 1
DotPi
  • 3,977
  • 6
  • 33
  • 53

2 Answers2

1

This may be off, perhaps someone more knowledgeable than me can chime in but here goes.

I found a thread from R-help mailing list (from 6 years ago) that talks about converting from DMS to decimal degrees using formula Decimal degrees = Degrees + (Minutes/60) + (Seconds/3600).

Using regular expressions to find the appropriate element, I construct a data.frame which is used to apply the above mentioned formula. Multiplying coordinates from South and West by -1 to make them negative.

xy <- c("39d47m01s N", "15d38m08s N", "12d45m01s N", "13d17m25s N", 
  "36d34m29s N", "24d46m34s S", "11d52m39s S", "39d47m01s N", "30d52m34s N", 
  "34d59m47s S")

nxy <- data.frame(degs = as.numeric(gsub("(^\\d+)(.+$)", "\\1", xy)),
                  mins = as.numeric(gsub("(^.+d)(\\d+)(m.+$)", "\\2", xy)),
                  secs = as.numeric(gsub("(^.+m)(\\d+)(s [A-Z]$)", "\\2", xy)),
                  direction = gsub("(^.+ )([A-Z])$", "\\2", xy))

nxy$indec <- with(nxy, degs + (mins/60) + (secs/3600))

nxy[nxy$direction %in% c("W", "S"), "indec"] <- nxy[nxy$direction %in% c("W", "S"), "indec"] * -1

nxy

   degs mins secs direction     indec
1    39   47    1         N  39.78361
2    15   38    8         N  15.63556
3    12   45    1         N  12.75028
4    13   17   25         N  13.29028
5    36   34   29         N  36.57472
6    24   46   34         S -24.77611
7    11   52   39         S -11.87750
8    39   47    1         N  39.78361
9    30   52   34         N  30.87611
10   34   59   47         S -34.99639

Or, you could make char2dms work for you.

nxy$char2dms <- as.numeric(sp::char2dms(xy, chd = "d", chm = "m", chs = "s"))

   degs mins secs direction     indec  char2dms
1    39   47    1         N  39.78361  39.78361
2    15   38    8         N  15.63556  15.63556
3    12   45    1         N  12.75028  12.75028
4    13   17   25         N  13.29028  13.29028
5    36   34   29         N  36.57472  36.57472
6    24   46   34         S -24.77611 -24.77611
7    11   52   39         S -11.87750 -11.87750
8    39   47    1         N  39.78361  39.78361
9    30   52   34         N  30.87611  30.87611
10   34   59   47         S -34.99639 -34.99639
Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197
0

I just figured it out.

Even though sp::char2dms accepts arguments called chd, chm and chs that are supposed to let us specify the separators used for degree, minutes and seconds, they do not seem to work.

After I changed the format in which the coordinates are represented, the function is working as expected. So, I just needed to make sure that my coordinates are in the format that sp::char2dms expects by default, which is of the form:

15d5'52.4394" N    145d40'26.04" E

The seperators for degree, minute and second are d,' and " respectively.

DotPi
  • 3,977
  • 6
  • 33
  • 53