With permission I am copying a private communication to the list.
On Oct 21, 2010, at 9:20 AM, Sadz A wrote:
> Hi,
>
> I think maybe I did not explain myself properly, I'll try again;
>
> I am trying to convert location data in DMS degrees to decimal
> degrees format.
>
> I have attached my data and below is the work I have done so far and
> notes explaining what I have done. The problem is negative 0, the
> +/- sign indicates direction so it is very important to have the
> right sign in front, but R takes 0 and -0 as 0.
>
> #approach
> #download 'gsubfn' from R CRAN.
>
> #please insert appropriate directory, the table is attached#
> data<-read.table("vol by genous lat lon.txt",header=T)
> names(data)
> attach(data)
> library(gsubfn)
>
> #the latitude data is in "MD_LATITUD" so to separate out the
numbers
> and convert to decimal degrees i used.......
At this point I realized that my earlier assumption that -0 == 0 might
not be as "obvious" as I had thought, at least when it applies to the
leading degrees entry in a latitude, which I was not thinking about
very clearly.>
> latitude<-as.vector(MD_LATITUD)
> x <- c(latitude)
> Convert <- function(d, m, s, dd = as.numeric(d), mm = as.numeric(m),
> ss = as.numeric(s)) sign(dd) * (abs(dd) + mm / 60 + ss / 3600)
The problem as I saw it was that the as.numeric conversion of d to dd
was throwing away the sign.
test <- c("-0:00:53", "-0:01:10.", "-0:01:26.",
"-0:01:38.", "-0:01:43",
"-0:01:59.", "-0:03:50.", "-0:04:46",
"-0:05:01.", "-0:05:16.",
"3:41:33.0", "3:43:09.4", "3:44:26.3",
"3:47:26.0", "3:48:19.3",
"3:52:13.4", "3:57:10.2", "4:29:37.6",
"5:01:28.4", "5:08:45.6" )
So I substituted an ifelse( grepl(d) -1,1) test for "-" from the
unconverted degree entry:
Convert <- function(d, m, s, dd = as.numeric(d), mm = as.numeric(m),
ss = as.numeric(s)){
ifelse(grepl("-", d),-1,1) * (abs(dd) + mm /
60 + ss / 3600) }
Lat<-strapply(test, "(.*):(.*):(.*)", Convert, simplify = TRUE)
> Lat
[1] -0.01472222 -0.01944444 -0.02388889 -0.02722222 -0.02861111
-0.03305556 -0.06388889 -0.07944444
[9] -0.08361111 -0.08777778 3.69250000 3.71927778 3.74063889
3.79055556 3.80536111 3.87038889
[17] 3.95283333 4.49377778 5.02455556 5.14600000
> Lat<-strapply(x, "(.*):(.*):(.*)", Convert, simplify = TRUE)
> Lat
>
> #as you can see in Lat there are lots of 0's, which should not be
> there but are because 'sign(dd)' takes +ve when +ve, -ve when -ve
> and multiplies it by 'abs(dd)....' which is correct, BUT for 0 it
> assigns niether +ve or -ve, giving 0 a 0, and anything times 0 is
> 0..........
>
> #I modified the code to
>
> latitude<-as.vector(MD_LATITUD)
> x <- c(latitude)
> Convert <- function(d, m, s, dd = as.numeric(d), mm = as.numeric(m),
> ss = as.numeric(s)) sign(ifelse(dd==0,sign(dd))) * (abs(dd) + mm /
> 60 + ss / 3600)
> Lat<-strapply(x, "(.*):(.*):(.*)", Convert, simplify = TRUE)
> Lat
>
> #so I now have the correct absolute decimal degrees in all cases and
> the correct direction in all cases except where there should be a
> -0!, because -0's are ignored and assumed to be the same as +0 which
> is wrong because the + and - indicate direction.
>
> # Do you know of a way I can get R to separate out the sign from
> MD_LATITUD, so that I can change
> # 'Convert <- function(d, m, s, dd = as.numeric(d), mm =
> as.numeric(m), ss = as.numeric(s)) sign(dd) * (abs(dd) + mm / 60 +
> ss / 3600)' to something like
> # 'Convert <- function(sign, d, m, s, dd = as.numeric(d), mm =
> as.numeric(m), ss = as.numeric(s)) sign * (abs(dd) + mm / 60 + ss /
> 3600) #(this does not work but something similar, or a different
> approach may?)
>
> Any help will be appreciated.
> Thank you
> sadz
>
>
> From: David Winsemius <dwinsemius at comcast.net>
> To: David Winsemius <dwinsemius at comcast.net>
> Cc: Sadz A <sadz_a1000 at yahoo.co.uk>; r-help at r-project.org
> Sent: Wed, 20 October, 2010 20:45:39
> Subject: Re: [R] Changing sign on absolute numbers 0 problems
>
>
> On Oct 20, 2010, at 3:19 PM, David Winsemius wrote:
>
> >
> > On Oct 20, 2010, at 11:47 AM, Sadz A wrote:
> >
> >> Hi,
> >>
> >> I am trying to do some calculations turning DMS data to decimal
> degrees using
> >> the formula (D+(M/60)+(S/3600)), some of the D's involve -ve
> numbers, the
> >> easiest way to do the calculation is to use absolute numbers then
> use the 'sign'
> >> function in R to change the answer back to the correct -ve or +ve,
> >>
> >> for example, if;
> >> D<--69
> >> M<-8
> >> S<-10
> >> then
> >> decimal<-D+(M/60)+(S/3600)
> >> -69+(8/60)+(10/3600) = this would equal -68.86389 (which is
> wrong, it should
> >> be -69.13611, so i used the following function)
> >>
> >> decimal<-(abs(D)+(M/60)+(S/3600))
> >> decimal.degs<-sign(D)*decimal
> >> decimal.degs
> >> -69.13611
> >>
> >> because ((69+(8/60)+(10/3600)=69.13611) and then the -sign is put
> back in.
> >>
> >> This works fine untill D=0
> >> because then 'sign' does not give 0 a +ve sign it takes it
as 0
> and multiplies
> >> decimal by 0 to give 0.
> >> example
> >> D<-0
> >> decimal<-D+(M/60)+(S/3600)
> >> decimal.degs<-sign(D)*decimal
> >> decimal.degs
> >> 0
> >>
> >> Is there anyway to get around this??????????
> >
> > I am not sure I understand the source of your distress. Why are
> you disturbed that 0 returns 0? ??????
> >
> >> and make D=0 a positive and not a 0 with sign or another
> function??????
> >
> > You can always define your own function:
> >
> > nonneg <- function(x) { 0 + !sign(x) }
> >
> > > nonneg(0)
> > [1] 1
>
> Insufficient testing. Try instead:
>
> > nonneg <- function(x) { 0+(x >= 0 )}
> > nonneg(c(-2,-1,0,1,2))
> [1] 0 0 1 1 1
>
>
> >
> >
> >>
> >> Any help is appreciated
> >> Thank you
> >> sadz
> >>
> >> ps please email me if you need more info
> > --David Winsemius, MD
> > West Hartford, CT
> >
> > ______________________________________________
> > R-help at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.
>
> David Winsemius, MD
> West Hartford, CT
>
>
> <vol by genous lat lon.txt>
David Winsemius, MD
West Hartford, CT