From 5f239357d96351d0cddfc62f980392bc461acf8e Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 11:22:59 -0700 Subject: [PATCH 01/13] add returnDist arg --- R/edge_dist.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/edge_dist.R b/R/edge_dist.R index 0abb2483..da7bdf28 100644 --- a/R/edge_dist.R +++ b/R/edge_dist.R @@ -48,6 +48,7 @@ edge_dist <- function(DT = NULL, coords = NULL, timegroup = NULL, splitBy = NULL, + returnDist = FALSE, fillNA = TRUE) { # due to NSE notes in R CMD check N <- Var1 <- Var2 <- value <- . <- NULL From a7187c9be99ab4afec00b595c72897ea607d9b67 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 12:14:09 -0700 Subject: [PATCH 02/13] add if returnDist flex return --- R/edge_dist.R | 14 ++++++++++---- man/edge_dist.Rd | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/R/edge_dist.R b/R/edge_dist.R index da7bdf28..e34043ee 100644 --- a/R/edge_dist.R +++ b/R/edge_dist.R @@ -105,7 +105,7 @@ edge_dist <- function(DT = NULL, ) ) } - } + } if (is.null(timegroup) && is.null(splitBy)) { splitBy <- NULL @@ -130,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)] @@ -144,6 +151,5 @@ edge_dist <- function(DT = NULL, } else { return(edges) } - } diff --git a/man/edge_dist.Rd b/man/edge_dist.Rd index 70c01b36..266de00d 100644 --- a/man/edge_dist.Rd +++ b/man/edge_dist.Rd @@ -5,7 +5,8 @@ \title{Distance based edge lists} \usage{ edge_dist(DT = NULL, threshold = NULL, id = NULL, coords = NULL, - timegroup = NULL, splitBy = NULL, fillNA = TRUE) + timegroup = NULL, splitBy = NULL, returnDist = FALSE, + fillNA = TRUE) } \arguments{ \item{DT}{input data.table} From addb424b377d81651dc9a887083b63526dffd936 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 12:24:31 -0700 Subject: [PATCH 03/13] add param returnDist to man --- R/edge_dist.R | 6 +++--- man/edge_dist.Rd | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/R/edge_dist.R b/R/edge_dist.R index e34043ee..f8736881 100644 --- a/R/edge_dist.R +++ b/R/edge_dist.R @@ -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. #' @@ -41,7 +41,7 @@ #' #' # 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, diff --git a/man/edge_dist.Rd b/man/edge_dist.Rd index 266de00d..f11ea40d 100644 --- a/man/edge_dist.Rd +++ b/man/edge_dist.Rd @@ -21,10 +21,12 @@ edge_dist(DT = NULL, threshold = NULL, id = NULL, coords = NULL, \item{splitBy}{(optional) character string or vector of grouping column name(s) upon which the grouping will be calculated} +\item{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.} + \item{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.} } \value{ -\code{edge_dist} returns a \code{data.table} with three columns: timegroup, ID1 and ID2. +\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. } @@ -57,7 +59,7 @@ group_times(DT, datetime = 'datetime', threshold = '20 minutes') # 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) } \seealso{ Other Edge-list generation: \code{\link{edge_nn}} From da0bc39fa3564efc32b69f3502623c27a75d5dfc Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 12:30:00 -0700 Subject: [PATCH 04/13] add initial returnDist tests --- tests/testthat/test-edge-dist.R | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/testthat/test-edge-dist.R b/tests/testthat/test-edge-dist.R index 00757e79..bd46429a 100644 --- a/tests/testthat/test-edge-dist.R +++ b/tests/testthat/test-edge-dist.R @@ -222,3 +222,44 @@ 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_lt(withDist[, max(distance)], + thresh) + +}) From cb3a3c5e82ca5f55d48447a29faed3154a912a6b Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 12:33:42 -0700 Subject: [PATCH 05/13] fix max / na.rm test error --- tests/testthat/test-edge-dist.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-edge-dist.R b/tests/testthat/test-edge-dist.R index bd46429a..e2e692d9 100644 --- a/tests/testthat/test-edge-dist.R +++ b/tests/testthat/test-edge-dist.R @@ -259,7 +259,7 @@ test_that('returnDist works', { expect_equal(withDist[is.na(ID2)], withDist[is.na(distance)]) - expect_lt(withDist[, max(distance)], + expect_lt(withDist[, max(distance, na.rm = TRUE)], thresh) }) From 14637fcc7846fcb35d2778dbb6bcf529dbc1b447 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 13:51:52 -0700 Subject: [PATCH 06/13] add test count NAs in distance and ID2 --- tests/testthat/test-edge-dist.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/testthat/test-edge-dist.R b/tests/testthat/test-edge-dist.R index e2e692d9..2d0144ea 100644 --- a/tests/testthat/test-edge-dist.R +++ b/tests/testthat/test-edge-dist.R @@ -259,6 +259,9 @@ test_that('returnDist works', { 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) From 0223719c62f098974e17a3e9264f8d35c202d5e8 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 13:53:27 -0700 Subject: [PATCH 07/13] add tests where fillNA is FALSE --- tests/testthat/test-edge-dist.R | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/testthat/test-edge-dist.R b/tests/testthat/test-edge-dist.R index 2d0144ea..9bd8f0e3 100644 --- a/tests/testthat/test-edge-dist.R +++ b/tests/testthat/test-edge-dist.R @@ -265,4 +265,20 @@ test_that('returnDist works', { 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) + }) From d36d730afb32de5cb50c0d43a7688890e5e8b120 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 13:56:58 -0700 Subject: [PATCH 08/13] bump version --- DESCRIPTION | 2 +- codemeta.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index ed8954f6..a8ee4b45 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -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", diff --git a/codemeta.json b/codemeta.json index 3df588ee..6b6b0cbe 100644 --- a/codemeta.json +++ b/codemeta.json @@ -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", @@ -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": { From 51c6d06af85c16946b3121452772f20a1ee5c609 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 13:58:53 -0700 Subject: [PATCH 09/13] fix missing v.0.1.9 date --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 6fcae062..1f861250 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,5 @@ # v 0.1.9 +# 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. From 6a9e5a3716073f51b334ed6844468c441ee05fc4 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 13:58:59 -0700 Subject: [PATCH 10/13] update NEWS --- NEWS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 1f861250..2ca0c72e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,6 @@ -# 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. From 13115689f3b7dbcdecacbc427f81673366dd2170 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 14:16:05 -0700 Subject: [PATCH 11/13] update README --- README.Rmd | 9 +++++++-- README.md | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index a63b9653..e39c56ac 100644 --- a/README.Rmd +++ b/README.Rmd @@ -20,9 +20,12 @@ knitr::opts_chunk$set(message = FALSE, # 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) | [Functions](#functions) | [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: @@ -32,6 +35,8 @@ For more details, see the [blog post](https://ropensci.org/blog/2018/12/04/spats + + ## News New edge-list generating functions added (feedback welcome as always!): diff --git a/README.md b/README.md index 31de9b6e..b484ca5b 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ checks](https://cranchecks.info/badges/summary/spatsoc)](https://cran.r-project. # spatsoc +### [News](#news) | [Installation](#installation) | [Usage](#usage) | [Functions](#functions) | [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 From 07f72afda6104b2f9c6cb44c8a479abc026e5d21 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 14:35:36 -0700 Subject: [PATCH 12/13] fix README redundant toc level --- README.Rmd | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.Rmd b/README.Rmd index e39c56ac..0376bf9a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -21,7 +21,7 @@ knitr::opts_chunk$set(message = FALSE, # spatsoc -### [News](#news) | [Installation](#installation) | [Usage](#usage) | [Functions](#functions) | [Contributing](#contributing) +### [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`. diff --git a/README.md b/README.md index b484ca5b..3f7c4935 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,10 @@ checks](https://cranchecks.info/badges/summary/spatsoc)](https://cran.r-project. # spatsoc -### [News](#news) | [Installation](#installation) | [Usage](#usage) | [Functions](#functions) | [Contributing](#contributing) +### [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 +`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 @@ -26,7 +26,7 @@ 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: From 8ae6ca738e7e4c58a8649c3bd74bb852dd33d3f7 Mon Sep 17 00:00:00 2001 From: Alec Robitaille Date: Thu, 6 Jun 2019 14:37:43 -0700 Subject: [PATCH 13/13] add NEWS link --- README.Rmd | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index 0376bf9a..fc1f3e13 100644 --- a/README.Rmd +++ b/README.Rmd @@ -37,7 +37,7 @@ 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` diff --git a/README.md b/README.md index 3f7c4935..f5a42614 100644 --- a/README.md +++ b/README.md @@ -38,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\!):