Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return distance between individuals with edge_dist #19

Merged
merged 13 commits into from
Jun 6, 2019
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: spatsoc
Title: Group Animal Relocation Data by Spatial and Temporal Relationship
Version: 0.1.9
Version: 0.1.10
Authors@R:
c(person(given = "Alec L.",
family = "Robitaille",
Expand Down
5 changes: 4 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# v 0.1.9
# v 0.1.10
* added optional return of distance between individuals with `edge_dist` ([PR 19](https://github.com/ropensci/spatsoc/pull/19))

# v 0.1.9 (2019-05-14)
* fixed bug for randomizations type 'step' and 'daily' ([PR 13](https://github.com/ropensci/spatsoc/pull/13)).
* clarified `SIMPLIFY=FALSE` in SNA vignette.

Expand Down
21 changes: 14 additions & 7 deletions R/edge_dist.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
#' The \code{splitBy} argument offers further control over grouping. If within your \code{DT}, you have multiple populations, subgroups or other distinct parts, you can provide the name of the column which identifies them to \code{splitBy}. \code{edge_dist} will only consider rows within each \code{splitBy} subgroup.
#'
#' @inheritParams group_pts
#' @param returnDist boolean indicating if the distance between individuals should be returned. If FALSE (default), only ID1, ID2 columns (and timegroup, splitBy columns if provided) are returned. If TRUE, another column "distance" is returned indicating the distance between ID1 and ID2.
#' @param fillNA boolean indicating if NAs should be returned for individuals that were not within the threshold distance of any other. If TRUE, NAs are returned. If FALSE, only edges between individuals within the threshold distance are returned.
#'
#'
#' @return \code{edge_dist} returns a \code{data.table} with three columns: timegroup, ID1 and ID2.
#' @return \code{edge_dist} returns a \code{data.table} with columns ID1, ID2, timegroup (if supplied) and any columns provided in splitBy. If 'returnDist' is TRUE, column 'distance' is returned indicating the distance between ID1 and ID2.
#'
#' The ID1 and ID2 columns represent the edges defined by the spatial (and temporal with \code{group_times}) thresholds.
#'
Expand All @@ -41,13 +41,14 @@
#'
#' # Edge list generation
#' edge_dist(DT, threshold = 100, id = 'ID',
#' coords = c('X', 'Y'), timegroup = 'timegroup', fillNA = TRUE)
#' coords = c('X', 'Y'), timegroup = 'timegroup', returnDist = TRUE, fillNA = TRUE)
edge_dist <- function(DT = NULL,
threshold = NULL,
id = NULL,
coords = NULL,
timegroup = NULL,
splitBy = NULL,
returnDist = FALSE,
fillNA = TRUE) {
# due to NSE notes in R CMD check
N <- Var1 <- Var2 <- value <- . <- NULL
Expand Down Expand Up @@ -104,7 +105,7 @@ edge_dist <- function(DT = NULL,
)
)
}
}
}

if (is.null(timegroup) && is.null(splitBy)) {
splitBy <- NULL
Expand All @@ -129,8 +130,15 @@ edge_dist <- function(DT = NULL,
as.matrix(stats::dist(.SD[, 2:3], method = 'euclidean'))
diag(distMatrix) <- NA
w <- which(distMatrix < threshold, arr.ind = TRUE)
list(ID1 = .SD[[1]][w[, 1]],
ID2 = .SD[[1]][w[, 2]])

if (returnDist) {
list(ID1 = .SD[[1]][w[, 1]],
ID2 = .SD[[1]][w[, 2]],
distance = distMatrix[w])
} else {
list(ID1 = .SD[[1]][w[, 1]],
ID2 = .SD[[1]][w[, 2]])
}
},
by = splitBy, .SDcols = c(id, coords)]

Expand All @@ -143,6 +151,5 @@ edge_dist <- function(DT = NULL,
} else {
return(edges)
}

}

11 changes: 8 additions & 3 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ knitr::opts_chunk$set(message = FALSE,
<!-- badges: end -->

# spatsoc
spatsoc is an R package for detecting spatial and temporal groups in GPS relocations. It can be used to convert GPS relocations to gambit-of-the-group format to build proximity-based social networks with grouping and edge-list generating functions. In addition, the `randomizations` function provides data-stream randomization methods suitable for GPS data and the `get_gbi` function generates group by individual matrices useful for building networks with `asnipe::get_network`.

See below for installation and basic usage.
### [News](#news) | [Installation](#installation) | [Usage](#usage) | [Contributing](#contributing)

`spatsoc` is an R package for detecting spatial and temporal groups in GPS relocations. It can be used to convert GPS relocations to gambit-of-the-group format to build proximity-based social networks with grouping and edge-list generating functions. In addition, the `randomizations` function provides data-stream randomization methods suitable for GPS data and the `get_gbi` function generates group by individual matrices useful for building networks with `asnipe::get_network`.

See below for [installation](#installation) and basic [usage](#usage).

For more details, see the [blog post](https://ropensci.org/blog/2018/12/04/spatsoc/) and vignettes:

Expand All @@ -32,7 +35,9 @@ For more details, see the [blog post](https://ropensci.org/blog/2018/12/04/spats



## News


## [News](http://spatsoc.robitalec.ca/news/index.html)
New edge-list generating functions added (feedback welcome as always!):

* `edge_nn`
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ checks](https://cranchecks.info/badges/summary/spatsoc)](https://cran.r-project.

# spatsoc

spatsoc is an R package for detecting spatial and temporal groups in GPS
relocations. It can be used to convert GPS relocations to
### [News](#news) | [Installation](#installation) | [Usage](#usage) | [Contributing](#contributing)

`spatsoc` is an R package for detecting spatial and temporal groups in
GPS relocations. It can be used to convert GPS relocations to
gambit-of-the-group format to build proximity-based social networks with
grouping and edge-list generating functions. In addition, the
`randomizations` function provides data-stream randomization methods
suitable for GPS data and the `get_gbi` function generates group by
individual matrices useful for building networks with
`asnipe::get_network`.

See below for installation and basic usage.
See below for [installation](#installation) and basic [usage](#usage).

For more details, see the [blog
post](https://ropensci.org/blog/2018/12/04/spatsoc/) and vignettes:
Expand All @@ -36,7 +38,7 @@ post](https://ropensci.org/blog/2018/12/04/spatsoc/) and vignettes:
- [Using spatsoc in social network
analysis](http://spatsoc.robitalec.ca/articles/using-in-sna.html)

## News
## [News](http://spatsoc.robitalec.ca/news/index.html)

New edge-list generating functions added (feedback welcome as always\!):

Expand Down
4 changes: 2 additions & 2 deletions codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
],
"issueTracker": "https://github.com/ropensci/spatsoc/issues",
"license": "https://spdx.org/licenses/GPL-3.0",
"version": "0.1.9",
"version": "0.1.10",
"programmingLanguage": {
"@type": "ComputerLanguage",
"name": "R",
Expand Down Expand Up @@ -224,7 +224,7 @@
],
"releaseNotes": "https://github.com/ropensci/spatsoc//blob/master/NEWS.md",
"readme": "https://github.com/ropensci/spatsoc/blob/master/README.md",
"fileSize": "366.364KB",
"fileSize": "366.853KB",
"contIntegration": "https://codecov.io/gl/robit.a/spatsoc",
"developmentStatus": "http://www.repostatus.org/#active",
"review": {
Expand Down
9 changes: 6 additions & 3 deletions man/edge_dist.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions tests/testthat/test-edge-dist.R
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,63 @@ test_that('returned IDs make sense', {
expect_true(eDT[ID1 == ID2, .N] == 0)

})



test_that('returnDist works', {
copyDT <- copy(DT)[, datetime := as.POSIXct(datetime)]
group_times(copyDT, datetime = 'datetime', threshold = '10 minutes')

thresh <- 50
withDist <- edge_dist(
copyDT,
threshold = thresh,
id = 'ID',
coords = c('X', 'Y'),
timegroup = 'timegroup',
returnDist = TRUE,
fillNA = TRUE
)

woDist <- edge_dist(
copyDT,
threshold = thresh,
id = 'ID',
coords = c('X', 'Y'),
timegroup = 'timegroup',
returnDist = FALSE,
fillNA = TRUE
)

expect_equal(withDist[, .(ID1, ID2, timegroup)],
woDist[, .(ID1, ID2, timegroup)])

expect_equal(nrow(withDist),
nrow(woDist))

expect_equal(withDist[is.na(ID2)],
withDist[is.na(distance)])

expect_equal(withDist[!is.na(ID2)],
withDist[!is.na(distance)])

expect_lt(withDist[, max(distance, na.rm = TRUE)],
thresh)


withDistNoNA <- edge_dist(
copyDT,
threshold = thresh,
id = 'ID',
coords = c('X', 'Y'),
timegroup = 'timegroup',
returnDist = TRUE,
fillNA = FALSE
)

expect_true(withDistNoNA[is.na(distance), .N] == 0)
expect_true(withDistNoNA[is.na(ID2), .N] == 0)
expect_lt(withDistNoNA[, max(distance, na.rm = TRUE)],
thresh)

})