Skip to content

Commit b4b6bdc

Browse files
committed
adding the new ds.kurtosis function
1 parent 40d1340 commit b4b6bdc

5 files changed

Lines changed: 184 additions & 6 deletions

File tree

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export(ds.heatmapPlot)
3535
export(ds.histogram)
3636
export(ds.isNA)
3737
export(ds.isValid)
38+
export(ds.kurtosis)
3839
export(ds.length)
3940
export(ds.levels)
4041
export(ds.lexis)

R/ds.kurtosis.R

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#'
2+
#' @title Calculates the kurtosis of a numeric variable
3+
#' @description This function calculates the kurtosis of a numeric variable.
4+
#' @details The function calculates the kurtosis of an input variable x with three different methods.
5+
#' The method is specified by the argument \code{method}. If x contains any missings, the function removes those before
6+
#' the calculation of the kurtosis. If \code{method} is set to 1 the following formula is used
7+
#' \eqn{ kurtosis= \frac{\sum_{i=1}^{N} (x_i - \bar(x))^4 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^2) /N)^(2) } - 3},
8+
#' where \eqn{ \bar{x} } is the mean of x and \eqn{N} is the number of observations. If \code{method} is set to 2
9+
#' the following formula is used \eqn{ kurtosis= ((N+1)*(\frac{\sum_{i=1}^{N} (x_i - \bar(x))^4 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^2) /N)^(2) } - 3) + 6)*((N-1)/((N-2)*(N-3)))}.
10+
#' If \code{method} is set to 3 the following formula is used \eqn{ kurtosis= (\frac{\sum_{i=1}^{N} (x_i - \bar(x))^4 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^2) /N)^(2) })*(1-1/N)^2 - 3}.
11+
#' This function is similar to the function \code{kurtosis} in R package \code{e1071}.
12+
#' @param x a string character, the name of a numeric variable.
13+
#' @param method an integer between 1 and 3 selecting one of the algorithms for computing kurtosis
14+
#' detailed below. The default value is set to 1.
15+
#' @param type a character which represents the type of analysis to carry out.
16+
#' If \code{type} is set to 'combine', 'combined', 'combines' or 'c', the global kurtosis is returned
17+
#' if \code{type} is set to 'split', 'splits' or 's', the kurtosis is returned separately for each study.
18+
#' if \code{type} is set to 'both' or 'b', both sets of outputs are produced.
19+
#' The default value is set to 'both'.
20+
#' @param datasources a list of \code{\link{DSConnection-class}} objects obtained after login.
21+
#' If the \code{datasources} argument is not specified
22+
#' the default set of connections will be used: see \code{\link{datashield.connections_default}}.
23+
#' @return a matrix showing the kurtosis of the input numeric variable, the number of valid observations and
24+
#' the validity message.
25+
#' @author Demetris Avraam, for DataSHIELD Development Team
26+
#' @export
27+
#'
28+
ds.kurtosis <- function(x=NULL, method=1, type='both', datasources=NULL){
29+
30+
# if no opal login details are provided look for 'opal' objects in the environment
31+
if(is.null(datasources)){
32+
datasources <- datashield.connections_find()
33+
}
34+
35+
if(is.null(x)){
36+
stop("Please provide the name of the input vector!", call.=FALSE)
37+
}
38+
39+
if(!(method %in% c(1,2,3))){
40+
stop("method must be an integer between 1 and 3", call.=FALSE)
41+
}
42+
43+
# enable valid aliases for "type" argument
44+
if(type == 'combine' | type == 'combined' | type == 'combines' | type == 'c') type <- 'combine'
45+
if(type == 'split' | type == 'splits' | type == 's') type <- 'split'
46+
if(type == 'both' | type == 'b' ) type <- 'both'
47+
48+
# the input variable might be given as column table (i.e. D$x)
49+
# or just as a vector not attached to a table (i.e. x)
50+
# we have to make sure the function deals with each case
51+
xnames <- extract(x)
52+
varname <- xnames$elements
53+
obj2lookfor <- xnames$holders
54+
55+
# check if the input object(s) is(are) defined in all the studies
56+
if(is.na(obj2lookfor)){
57+
defined <- isDefined(datasources, varname)
58+
}else{
59+
defined <- isDefined(datasources, obj2lookfor)
60+
}
61+
62+
# call the internal function that checks the input object is of the same class in all studies.
63+
typ <- checkClass(datasources, x)
64+
65+
# the input object must be a numeric or an integer vector
66+
if(typ != 'integer' & typ != 'numeric'){
67+
message(paste0(x, " is of type ", typ, "!"))
68+
stop("The input object must be an integer or numeric vector.", call.=FALSE)
69+
}
70+
71+
if (type=='split' | type=='both'){
72+
calltext.split <- call("kurtosisDS1", x, method)
73+
output.split <- DSI::datashield.aggregate(datasources, calltext.split)
74+
mat.split <- matrix(as.numeric(matrix(unlist(output.split), nrow=length(datasources), byrow=TRUE)[,1:2]),nrow=length(datasources))
75+
validity <- matrix(unlist(output.split), nrow=length(datasources), byrow=TRUE)[,3]
76+
mat.split <- data.frame(cbind(mat.split, validity))
77+
rownames(mat.split) <- names(output.split)
78+
colnames(mat.split) <- c('Kurtosis', 'Nvalid', 'ValidityMessage')
79+
}
80+
81+
if (type=='combine' | type=='both'){
82+
global.mean <- ds.mean(x, type='combine')$Global.Mean[,'EstimatedMean']
83+
#global.var <- ds.var(x, type='combine')$Global.Variance[,'EstimatedVar']
84+
85+
if (is.na(global.mean)){
86+
stop("FAILED: The number of valid observations in one or more studies is less than nfilter.tab. \n Check that by using the argument type=='split'", call.=FALSE)
87+
}else{
88+
calltext.combined <- call("kurtosisDS2", x, global.mean)
89+
output.combined <- DSI::datashield.aggregate(datasources, calltext.combined)
90+
91+
Global.sum.quartics <- 0
92+
Global.sum.squares <- 0
93+
Global.Nvalid <- 0
94+
for (s in 1:length(datasources)){
95+
Global.sum.quartics <- Global.sum.quartics + output.combined[[s]]$Sum.quartics
96+
Global.sum.squares <- Global.sum.squares + output.combined[[s]]$Sum.squares
97+
Global.Nvalid <- Global.Nvalid + output.combined[[s]]$Nvalid
98+
}
99+
100+
g2.global <- ((Global.sum.quartics/Global.Nvalid)/(Global.sum.squares/Global.Nvalid)^(2))-3
101+
102+
if(method==1){
103+
Global.kurtosis <- g2.global
104+
combinedMessage <- "VALID ANALYSIS"
105+
}
106+
if(method==2){
107+
Global.kurtosis <- ((Global.Nvalid + 1) * g2.global + 6) * (Global.Nvalid - 1)/((Global.Nvalid - 2) * (Global.Nvalid - 3))
108+
combinedMessage <- "VALID ANALYSIS"
109+
}
110+
if(method==3){
111+
Global.kurtosis <- (g2.global + 3) * (1 - 1/Global.Nvalid)^2 - 3
112+
combinedMessage <- "VALID ANALYSIS"
113+
}
114+
mat.combined <- data.frame(cbind(Global.kurtosis, Global.Nvalid, combinedMessage))
115+
rownames(mat.combined) <- 'studiesCombined'
116+
colnames(mat.combined) <- c('Kurtosis', 'Nvalid', 'ValidityMessage')
117+
118+
}
119+
}
120+
121+
if (type=='split'){
122+
return(Kurtosis.by.Study=mat.split)
123+
}
124+
125+
if (type=="combine") {
126+
return(Global.Kurtosis=mat.combined)
127+
}
128+
129+
if (type=="both") {
130+
return(list(Kurtosis.by.Study=mat.split, Global.Kurtosis=mat.combined))
131+
}
132+
133+
}

R/ds.skewness.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
#' @details The function calculates the skewness of an input variable x with three different methods.
55
#' The method is specified by the argument \code{method}. If x contains any missings, the function removes those before
66
#' the calculation of the skewness. If \code{method} is set to 1 the following formula is used
7-
#' \eqn{ skewness= \frac{\sum_{i=1}^{N} (x_i - \bar(x))^3 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^3) /N)^(3/2) }},
7+
#' \eqn{ skewness= \frac{\sum_{i=1}^{N} (x_i - \bar(x))^3 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^2) /N)^(3/2) }},
88
#' where \eqn{ \bar{x} } is the mean of x and \eqn{N} is the number of observations. If \code{method} is set to 2
9-
#' the following formula is used \eqn{ skewness= \frac{\sum_{i=1}^{N} (x_i - \bar(x))^3 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^3) /N)^(3/2) } * \frac{\sqrt(N(N-1)}{n-2}}.
10-
#' If \code{method} is set to 3 the following formula is used \eqn{ skewness= \frac{\sum_{i=1}^{N} (x_i - \bar(x))^3 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^3) /N)^(3/2) } * (\frac{N-1}{N})^(3/2)}.
9+
#' the following formula is used \eqn{ skewness= \frac{\sum_{i=1}^{N} (x_i - \bar(x))^3 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^2) /N)^(3/2) } * \frac{\sqrt(N(N-1)}{n-2}}.
10+
#' If \code{method} is set to 3 the following formula is used \eqn{ skewness= \frac{\sum_{i=1}^{N} (x_i - \bar(x))^3 /N}{(\sum_{i=1}^{N} ((x_i - \bar(x))^2) /N)^(3/2) } * (\frac{N-1}{N})^(3/2)}.
1111
#' This function is similar to the function \code{skewness} in R package \code{e1071}.
1212
#' @param x a string character, the name of a numeric variable.
1313
#' @param method an integer between 1 and 3 selecting one of the algorithms for computing skewness

man/ds.kurtosis.Rd

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

man/ds.skewness.Rd

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

0 commit comments

Comments
 (0)