[R-sig-Geo] Calculating distance to nest with spDistsN1

Robert J. Hijmans r.hijmans at gmail.com
Tue Sep 30 18:16:02 CEST 2014


Anna-Marie,

If I (and Frede) understand the problem, then you can use the
raster::pointDistance function or similar functions in the geosphere
package.

dat <- read.table(text =
"lon lat Date Time Speed Direction col_lat col_long dist_col trip_no
bird_id trip_id DT date_time
7.87248 54.1866 '04.07.2014' '09:25:00' 0.02 314.57 54.1866 7.8724 0.0
1 1 1.1 '04.07.2014 09:25:00' '2014-07-04 09:25:00'
7.87148 54.1869 '04.07.2014' '09:30:00' 19.11 1.31 54.1866 7.8724 0.1
2 1 2.1 '04.07.2014 09:30:00' '2014-07-04 09:30:00'
7.87166 54.1850 '04.07.2014' '09:35:00' 14.98 224.79 54.1866 7.8724
0.2 3 1 3.1 '04.07.2014 09:35:00' '2014-07-04 09:35:00'
7.87168 54.1851 '04.07.2014' '09:35:00' 14.98 224.79 54.1866 7.8724
0.2 4 1 4.1 '04.07.2014 09:35:00' '2014-07-04 09:35:00'
7.88635 54.1569 '04.07.2014' '09:40:00' 11.44 136.97 54.2 7.9 3.4 1 2
1.2 '04.07.2014 09:40:00' '2014-07-04 09:40:00'
7.92096 54.1363 '04.07.2014' '09:45:00' 0.28 262.14 54.2 7.9 6.4 2 2
2.2 '04.07.2014 09:45:00' '2014-07-04 09:45:00'
7.91931 54.1360 '04.07.2014' '09:50:00' 0.42 218.89 54.2 7.9 6.4 3 2
3.2 '04.07.2014 09:50:00' '2014-07-04 09:50:00'",
                  h = TRUE, sep = " ")


library(raster)
dat$distance <- pointDistance(dat[, c('lon', 'lat')], dat[,
c('col_long', 'col_lat')], lonlat=TRUE)
dat


Robert

On Mon, Sep 29, 2014 at 11:33 PM, Anna-Marie Corman <annajess at gmx.de> wrote:
> Dear St. John and Frede,
>
> thanks a lot for your help. I think I made my question not clear enough
> and was confusing instead. Sorry for this.
> The data are ordered: there are several birds and each bird has done a
> varying number of trips. The coordinates are the different positions of
> each bird's trip starting and ending at its nest. So, first, there is
> bird 1 with several prositions of trip 1, following several positions of
> trip 2 and so on. That is why I produced a new unique variable where
> trip no. and bird id are included so that there are no (timestamp)
> replicates. So the data set starts with trip_id 1.1 several times and
> then 1.2,  1.3 and so on.
> Col_long and col_lat are the nest positions of each bird. I tried to
> calculate the distance of each GPS position during the trips
> (coordinates) to the corresponding nest of the relevant bird. So, I
> could do it with spDistsN1, but then I have to separate the different
> birds, i.e. use several datasets. But as this would take a lot of time,
> I would rather use one dataset with all birds included...
>
> Here is a structure of my data:Formal class 'SpatialPointsDataFrame'
> [package "sp"] with 5 slots
>    ..@ data       :'data.frame':    13099 obs. of  14 variables:
>    .. ..$ Date     : Factor w/ 69 levels "01.08.2014","01.09.2014",..: 7
> 7 7 7 7 7 7 7 7 7 ...
>    .. ..$ Time     : Factor w/ 2391 levels " 03:00:35"," 03:00:44",..:
> 2156 2157 2158 2160 2161 2162 2163 2165 2166 2168 ...
>    .. ..$ Speed    : num [1:13099] 0.02 19.11 14.98 11.44 0.28 ...
>    .. ..$ Direction: num [1:13099] 314.57 1.31 224.79 136.97 262.14 ...
>    .. ..$ col_lat  : num [1:13099] 54.2 54.2 54.2 54.2 54.2 ...
>    .. ..$ col_long : num [1:13099] 7.87 7.87 7.87 7.87 7.87 ...
>    .. ..$ trip_no  : int [1:13099] 1 1 1 1 1 1 1 1 1 1 ...
>    .. ..$ bird_id  : int [1:13099] 1 1 1 1 1 1 1 1 1 1 ...
>    .. ..$ trip_id  : chr [1:13099] "1.1" "1.1" "1.1" "1.1" ...
>    .. ..$ DT       : chr [1:13099] "04.07.2014 09:25:00" "04.07.2014
> 09:30:00" "04.07.2014 09:35:00" "04.07.2014 09:40:00" ...
>    .. ..$ date_time: POSIXct[1:13099], format: "2014-07-04 09:25:00"
> "2014-07-04 09:30:00" "2014-07-04 09:35:00" ...
>    .. ..$ dist     : num [1:13099] 0 0.0726 0.2122 3.2709 3.2187 ...
>    .. ..$ speed    : num [1:13099] 0 0.871 2.547 39.25 38.625 ...
>    ..@ coords.nrs : int [1:2] 4 3
>    ..@ coords     : num [1:13099, 1:2] 7.87 7.87 7.87 7.89 7.92 ...
>    .. ..- attr(*, "dimnames")=List of 2
>    .. .. ..$ : NULL
>    .. .. ..$ : chr [1:2] "Long" "Lat"
>    ..@ bbox       : num [1:2, 1:2] 5.36 53.71 8.57 57.01
>    .. ..- attr(*, "dimnames")=List of 2
>    .. .. ..$ : chr [1:2] "Long" "Lat"
>    .. .. ..$ : chr [1:2] "min" "max"
>    ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slots
>    .. .. ..@ projargs: chr NA
>
> I will try St. John's solution out... Maybe it is also possible with a
> loop: dat$home <- spDistsN1(coordinates(dat at coords),
> matrix(c(dat$col_long[i],dat$col_lat[i]), nrow = 1), longlat = T)
> but I'm not really sure which for argument to use then...
>
> Thanks a lot again.
>
> Best wishes,
> Anna
>
> Am 30.09.2014 08:18, schrieb Frede Aakmann Tøgersen:
>> Hi
>>
>> Using spDists  will also give Anna-Maria the distance between a bird's nest and the endpoints of another birds trips.
>>
>> Here is a way to achieve what I think Anna-Maria wants. Working with a SpatialPointsDataFrame objects complicates things so I will show how to it with an ordinary data.frame. Also I think that Anna-Maria has coded the trip_no, bird_id, and trip_id variables in a wrong way (see how I think the data should look below).
>>
>> My assumptions:
>>
>> 1. The coordinates(dat) is the coordinates of end of trips
>> 2. col_lat and col_long is the coordinates of nests
>> 3. My example has two birds with id 1 and 2
>> 4. Bird 1 has 4 trips with id 1,2,3,4 and bird 2 has 3 trips with id 1,2,3
>>
>> ## Here is a somewhat altered version of Anna-Maria's data:
>> dat <- read.table(text =
>> "lon lat Date Time Speed Direction col_lat col_long dist_col trip_no bird_id trip_id DT date_time
>> 7.87248 54.1866 '04.07.2014' '09:25:00' 0.02 314.57 54.1866 7.8724 0.0 1 1 1.1 '04.07.2014 09:25:00' '2014-07-04 09:25:00'
>> 7.87148 54.1869 '04.07.2014' '09:30:00' 19.11 1.31 54.1866 7.8724 0.1 2 1 2.1 '04.07.2014 09:30:00' '2014-07-04 09:30:00'
>> 7.87166 54.1850 '04.07.2014' '09:35:00' 14.98 224.79 54.1866 7.8724 0.2 3 1 3.1 '04.07.2014 09:35:00' '2014-07-04 09:35:00'
>> 7.87168 54.1851 '04.07.2014' '09:35:00' 14.98 224.79 54.1866 7.8724 0.2 4 1 4.1 '04.07.2014 09:35:00' '2014-07-04 09:35:00'
>> 7.88635 54.1569 '04.07.2014' '09:40:00' 11.44 136.97 54.2 7.9 3.4 1 2 1.2 '04.07.2014 09:40:00' '2014-07-04 09:40:00'
>> 7.92096 54.1363 '04.07.2014' '09:45:00' 0.28 262.14 54.2 7.9 6.4 2 2 2.2 '04.07.2014 09:45:00' '2014-07-04 09:45:00'
>> 7.91931 54.1360 '04.07.2014' '09:50:00' 0.42 218.89 54.2 7.9 6.4 3 2 3.2 '04.07.2014 09:50:00' '2014-07-04 09:50:00'",
>>                    h = TRUE, sep = " ")
>>
>> ## Now for each bird nest find the distances in km to end point of each birds trips:
>> trip_distances <- sapply(unique(dat$bird_id), function(id)
>>      spDistsN1(as.matrix(subset(dat, bird_id == id , select = c("lon", "lat"))),
>>                as.matrix(subset(dat, bird_id == id, select = c("col_long", "col_lat"))[1,]), longlat=T))
>>
>> ## have a look at the result
>> print(trip_distances)
>>
>> ## unlist the trip_distances and add that as a column to dat. The order of the unlist should match the row order of dat.
>> dat$trip_distances  <- unlist(trip_distances)
>>
>> ## print dat
>> print(dat)
>>
>> Hope that is what Anna-Maria really wants.
>>
>> Yours sincerely / Med venlig hilsen
>>
>>
>> Frede Aakmann Tøgersen
>> Specialist, M.Sc., Ph.D.
>> Plant Performance & Modeling
>>
>> Technology & Service Solutions
>> T +45 9730 5135
>> M +45 2547 6050
>> frtog at vestas.com
>> http://www.vestas.com
>>
>> Company reg. name: Vestas Wind Systems A/S
>> This e-mail is subject to our e-mail disclaimer statement.
>> Please refer to www.vestas.com/legal/notice
>> If you have received this e-mail in error please contact the sender.
>>
>>
>>> -----Original Message-----
>>> From: r-sig-geo-bounces at r-project.org [mailto:r-sig-geo-bounces at r-
>>> project.org] On Behalf Of St John Brown
>>> Sent: 30. september 2014 03:04
>>> To: Anna-Marie Corman; R-sig-Geo at r-project.org
>>> Subject: Re: [R-sig-Geo] Calculating distance to nest with spDistsN1
>>>
>>> Anna-Marie,
>>>
>>> If you look at the documentation for spDistsN1 (i.e. run "?spDistsN1"), you
>>> will see that the second argument is suppose to be a single 2D point, and not
>>> many 2D points. As per the documentation descripttion, "the function
>>> returns a vector of distances between a matrix of 2D points ... and a single 2D
>>> point."
>>>
>>> I am not 100% sure I understand what you are trying to do, but I think what
>>> you are looking for is the spDists function. Compare the results of my output
>>> from using spDistsN1 versus spDists.
>>>
>>> I hope this helps.
>>>
>>> St. John
>>>
>>> make_locations = function(n){
>>>    lon = runif(n=n,min=7,max=8)
>>>    lat = runif(n=n,min=50,max=60)
>>>    locations = matrix(append(lon, lat), nrow=n, ncol=2)
>>>    colnames(locations) = c("lon", "lat")
>>>    rownames(locations) = 1:n
>>>    return(locations)
>>> }
>>>
>>> set.seed(1)
>>> flight_locations = make_locations(n=3)
>>> nest_locations = make_locations(n=3)
>>>
>>> flight_locations
>>> nest_locations
>>>
>>> spDistsN1(flight_locations, nest_locations[1,], longlat=T)
>>> spDists(flight_locations, nest_locations, longlat=T)
>>>
>>>
>>> On Monday, September 29, 2014 5:47 AM, Anna-Marie Corman
>>> <annajess at gmx.de> wrote:
>>>
>>>
>>>
>>>
>
>
>         [[alternative HTML version deleted]]
>
>
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo at r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>



More information about the R-sig-Geo mailing list