Skip to content

Commit cda41b6

Browse files
Merge pull request #233 from StuartWheater/master
Update with 6.0.1 changes
2 parents 997bfcb + 8b9ef16 commit cda41b6

13 files changed

Lines changed: 166 additions & 102 deletions

DESCRIPTION

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
Package: dsBaseClient
22
Title: DataSHIELD Client Functions
3-
Version: 6.0.0
3+
Version: 6.0.1
44
Author: DataSHIELD Developers <datashield@newcastle.ac.uk>
55
Maintainer: DataSHIELD Developers <datashield@newcastle.ac.uk>
66
Description: DataSHIELD client functions for the client side.
77
License: GPL-3
8-
Depends: R (>= 3.5.0),
9-
DSI
8+
Depends:
9+
R (>= 3.5.0),
10+
DSI (>= 1.1.0)
1011
Imports:
1112
fields,
1213
metafor

R/ds.dataFrameFill.R

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,14 @@ ds.dataFrameFill <- function(df.name=NULL, newobj=NULL, datasources=NULL){
116116
# if the datasets share the same variables then the function stops
117117
check.indicator <- c()
118118
for (i in 1:length(datasources)){
119-
if(length(column.names[[i]])==length(allNames)){check.indicator[i] <- 0}
120-
else{check.indicator[i] <- 1}
119+
if(length(setdiff(allNames,column.names[[i]])) > 0){
120+
check.indicator[i] <- 1
121+
}else{
122+
check.indicator[i] <- 0}
121123
}
122124

123125
if(sum(check.indicator)==0){
124-
stop("The dataframes have the same variables!", call.=FALSE)
126+
stop("The dataframes have the same variables. There are no missing variables to fill!", call.=FALSE)
125127
}
126128

127129
if(!is.null(allNames)){
@@ -130,7 +132,19 @@ ds.dataFrameFill <- function(df.name=NULL, newobj=NULL, datasources=NULL){
130132
allNames.transmit <- NULL
131133
}
132134

133-
calltext <- call("dataFrameFillDS", df.name, allNames.transmit)
135+
# get the class of each variable in the dataframes
136+
class.list <- lapply(allNames, function(x){dsBaseClient::ds.class(paste0(df.name, '$', x))})
137+
class.vect1 <- lapply(class.list, function(x){unlist(x)})
138+
class.vect2 <- lapply(class.vect1, function(x){x[which(x != 'NULL')[[1]]]})
139+
class.vect2 <- unname(unlist(class.vect2))
140+
141+
if(!is.null(class.vect2)){
142+
class.vect.transmit <- paste(class.vect2,collapse=",")
143+
}else{
144+
class.vect.transmit <- NULL
145+
}
146+
147+
calltext <- call("dataFrameFillDS", df.name, allNames.transmit, class.vect.transmit)
134148
DSI::datashield.assign(datasources, newobj, calltext)
135149

136150
#############################################################################################################

R/ds.names.R

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,85 @@
11
#'
2-
#' @title Gets the names of a server-side list
3-
#' @description Function to get the names of an object that is stored on the server-side.
4-
#' @details This function is similar to the R function \code{names}.
5-
#' In DataSHIELD the use of this function is restricted to objects of type list.
6-
#'
7-
#' Server function called: \code{namesDS}
8-
#' @param x a character string specifying the name of the list.
9-
#' @param datasources a list of \code{\link{DSConnection-class}}
10-
#' objects obtained after login. If the \code{datasources} argument is not specified
11-
#' the default set of connections will be used: see \code{\link{datashield.connections_default}}.
2+
#' @title Return the names of a list object
3+
#' @description Returns the names of a designated server-side list
4+
#' @details ds.names calls aggregate function namesDS. This function is similar to
5+
#' the native R function \code{names} but it does not subsume all functionality,
6+
#' for example, it only works to extract names that already exist,
7+
#' not to create new names for objects. The function is restricted to objects of
8+
#' type list, but this includes objects that have a primary class other than list but which
9+
#' return TRUE to the native R function {is.list}. As an example this includes
10+
#' the multi-component object created by fitting a generalized linear model
11+
#' using ds.glmSLMA. The resultant object saved on each server separately
12+
#' is formally of class "glm" and "ls" but responds TRUE to is.list(),
13+
#' @param xname a character string specifying the name of the list.
14+
#' @param datasources a list of \code{\link{DSConnection-class}}
15+
#' objects obtained after login that represent the particular data sources
16+
#' (studies) to be addressed by the function call. If the \code{datasources}
17+
#' argument is not specified the default set of connections will be used:
18+
#' see \code{\link{datashield.connections_default}}.
1219
#' @return \code{ds.names} returns to the client-side the names
13-
#' of a list stored on the server-side.
14-
#' @author DataSHIELD Development Team
20+
#' of a list object stored on the server-side.
21+
#' @author Amadou Gaye, updated by Paul Burton for DataSHIELD development
22+
#' team 25/06/2020
1523
#' @export
1624
#' @examples
1725
#' \dontrun{
18-
#'
26+
#'
1927
#' ## Version 6, for version 5 see the Wiki
20-
#'
28+
#'
2129
#' # connecting to the Opal servers
22-
#'
30+
#'
2331
#' require('DSI')
2432
#' require('DSOpal')
2533
#' require('dsBaseClient')
2634
#'
2735
#' builder <- DSI::newDSLoginBuilder()
28-
#' builder$append(server = "study1",
29-
#' url = "http://192.168.56.100:8080/",
30-
#' user = "administrator", password = "datashield_test&",
36+
#' builder$append(server = "study1",
37+
#' url = "http://192.168.56.100:8080/",
38+
#' user = "administrator", password = "datashield_test&",
3139
#' table = "CNSIM.CNSIM1", driver = "OpalDriver")
32-
#' builder$append(server = "study2",
33-
#' url = "http://192.168.56.100:8080/",
34-
#' user = "administrator", password = "datashield_test&",
40+
#' builder$append(server = "study2",
41+
#' url = "http://192.168.56.100:8080/",
42+
#' user = "administrator", password = "datashield_test&",
3543
#' table = "CNSIM.CNSIM2", driver = "OpalDriver")
3644
#' builder$append(server = "study3",
37-
#' url = "http://192.168.56.100:8080/",
38-
#' user = "administrator", password = "datashield_test&",
45+
#' url = "http://192.168.56.100:8080/",
46+
#' user = "administrator", password = "datashield_test&",
3947
#' table = "CNSIM.CNSIM3", driver = "OpalDriver")
4048
#' logindata <- builder$build()
41-
#'
42-
#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D")
43-
#'
44-
#' #Create a list in the server-side
45-
#'
49+
#'
50+
#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D")
51+
#'
52+
#' #Create a list in the server-side
53+
#'
4654
#' ds.asList(x.name = "D",
4755
#' newobj = "D.list",
4856
#' datasources = connections)
49-
#'
57+
#'
5058
#' #Get the names of the list
51-
#'
52-
#' ds.names(x = "D.list",
59+
#'
60+
#' ds.names(xname = "D.list",
5361
#' datasources = connections)
5462
#'
55-
#'
63+
#'
5664
#' # clear the Datashield R sessions and logout
5765
#' datashield.logout(connections)
5866
#'
5967
#' }
6068
#'
61-
ds.names <- function(x=NULL, datasources=NULL){
69+
ds.names <- function(xname=NULL, datasources=NULL){
6270

6371
# look for DS connections
6472
if(is.null(datasources)){
6573
datasources <- datashield.connections_find()
6674
}
6775

68-
if(is.null(x)){
76+
if(is.null(xname)){
6977
stop("Please provide the name of the input list!", call.=FALSE)
70-
}else{
71-
defined <- isDefined(datasources, x)
72-
}
73-
74-
# call the internal function that checks the input object is of the same class in all studies.
75-
typ <- checkClass(datasources, x)
76-
77-
# the input object must be a list
78-
if(!('list' %in% typ)){
79-
stop("The input object must be a list.", call.=FALSE)
8078
}
8179

82-
# call the server side function that does the job.
83-
cally <- paste0('namesDS(', x, ')')
84-
output <- DSI::datashield.aggregate(datasources, as.symbol(cally))
80+
calltext<-call("namesDS", xname)
81+
output<-datashield.aggregate(datasources,calltext)
8582
return(output)
86-
8783
}
84+
85+
#ds.names

R/ds.summary.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ ds.summary <- function(x=NULL, datasources=NULL){
174174
if("list" %in% typ){
175175
for(i in 1:numsources){
176176
l <- DSI::datashield.aggregate(datasources[i], call('lengthDS', x))[[1]]
177-
elts <- DSI::datashield.aggregate(datasources[i], as.symbol(paste0('namesDS(', x, ')' )))[[1]]
177+
elts <- DSI::datashield.aggregate(datasources[i], call('namesDS', x))[[1]]
178178
if(is.null(elts)){
179179
stdsummary <- list('class'=typ, 'length'=l)
180180
}else{

R/meanByClassHelper4.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ meanByClassHelper4 <- function(dtsource, alist, initialtable, variable=NA, categ
2626
newsubsets <- append(newsubsets, name2use)
2727
}
2828
}else{
29-
cally <- paste0('namesDS(', alist, ')')
30-
subsetnames <- unique(unlist(DSI::datashield.aggregate(dtsource, as.symbol(cally))))
29+
cally <- call('namesDS', alist)
30+
subsetnames <- unique(unlist(DSI::datashield.aggregate(dtsource, cally)))
3131
for(m in 1:length(subsetnames)){
3232
name2use <- paste0(unlist(strsplit(paste0(initialtable,'.',subsetnames[m]), '.level_')), collapse='')
3333
DSI::datashield.assign(dtsource, name2use, as.symbol(paste0(alist,'$',subsetnames[m])))

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ DataSHIELD client side base R library.
88

99
| Branch | dsBase status | dsBaseClient status | dsBaseClient tests |
1010
| -------- | ------------ | ------------------- | ------------------ |
11-
| Master | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBase?branchName=master)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=3&branchName=master) | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBaseClient?branchName=master)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=master) | [Tests](https://datashield.github.io/testStatus/dsBaseClient/master/latest/) |
12-
| v6.1-dev | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBase?branchName=v6.0-dev)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=3&branchName=v6.1-dev) | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBaseClient?branchName=v6.1-dev)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=v6.1-dev) | [Tests](https://datashield.github.io/testStatus/dsBaseClient/v6.1-dev/latest/) |
13-
11+
| Master | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBase?branchName=master)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=master) | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBaseClient?branchName=master)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=master) | [Tests](https://datashield.github.io/testStatus/dsBaseClient/master/latest/) |
12+
| v6.0.2-dev | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBase?branchName=v6.0.2-dev)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=v6.0.2-dev) | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBaseClient?branchName=v6.0.2-dev)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=v6.0.2-dev) | [Tests](https://datashield.github.io/testStatus/dsBaseClient/v6.0.2-dev/latest/) |
13+
| v6.1-dev | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBase?branchName=v6.1-dev)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=v6.1-dev) | [![Build Status](https://dev.azure.com/datashield-testing/datashield/_apis/build/status/datashield.dsBaseClient?branchName=v6.1-dev)](https://dev.azure.com/datashield-testing/datashield/_build/latest?definitionId=1&branchName=v6.1-dev) | [Tests](https://datashield.github.io/testStatus/dsBaseClient/v6.1-dev/latest/) |
1414

1515

1616
[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html)
@@ -31,4 +31,4 @@ Detailed instructions on how to install DataSHIELD are at https://www.datashield
3131
| obiba CRAN | Where you probably should install DataSHIELD from. |
3232
| releases | Stable releases. |
3333
| master branch | Mostly in sync with the latest release, changes rarely. |
34-
| v6.0-dev branch (or similar) | Bleeding edge development. We make no claims that this branch is fully functional at any given time. |
34+
| v6.1-dev branch (or similar) | Bleeding edge development. We make no claims that this branch is fully functional at any given time. |

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ resources:
4747
type: github
4848
endpoint: datashield-testing
4949
name: datashield/datashield-infrastructure
50-
ref: refs/tags/6.0.1
50+
ref: refs/tags/6.0.2
5151

5252

5353
#########################################################################################

man/ds.names.Rd

Lines changed: 39 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-arg-ds.names.R

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@ connect.studies.dataset.cnsim(list("LAB_TSC"))
2121
context("ds.names::arg::test errors")
2222
test_that("simple ds.names errors", {
2323
expect_error(ds.names(), "Please provide the name of the input list!", fixed=TRUE)
24-
expect_error(ds.names(x="D$LAB_TSC"), "The input object must be a list.", fixed=TRUE)
24+
25+
res <- ds.names(x="D$LAB_TSC")
26+
27+
expect_length(res, 3)
28+
expect_length(res$sim1, 2)
29+
expect_length(res$sim1$error.message, 1)
30+
expect_equal(res$sim1$error.message, "The input object is not of class <list>", fixed=TRUE)
31+
expect_length(res$sim1$trace.message, 1)
32+
expect_equal(res$sim1$trace.message, "numeric")
2533
})
2634

2735
#

tests/testthat/test-smk-ds.dataFrameFill-donothing.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ test_that("dataFrameFill_donothing", {
4242
expect_equal(colnamesD$sim3[2], "LAB_TRIG")
4343
expect_equal(colnamesD$sim3[3], "LAB_HDL")
4444

45-
expect_error(ds.dataFrameFill(df.name="D", newobj="filled_df"), "The dataframes have the same variables!")
45+
expect_error(ds.dataFrameFill(df.name="D", newobj="filled_df"), "The dataframes have the same variables. There are no missing variables to fill!")
4646
})
4747

4848
#

0 commit comments

Comments
 (0)