The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

1. Building discrete distributional data

Survey data are usually stored as microdata: one row per respondent, with some categorical variables (gender, faculty, age class, …) and a set of items measured on an ordinal scale (e.g. a 1-7 Likert scale). When the interest is in groups of respondents rather than in single individuals, each group can be described, for each item, by the frequency distribution of the scores given by its members. The resulting table, with groups in the rows, items in the columns and a discrete distribution in each cell, is a discrete distributional data table: the object of the DDAWASS package.

This vignette shows how to build such a table (a MatD object) from standard data.

library(DDAWASS)

The data: evaluation of the orientation services

We use the univer data of the CUB package: a survey on the evaluation of the orientation services of the University of Naples Federico II (2002), with 2179 students who rated, on a 1-7 scale (1 = extremely unsatisfied, 7 = extremely satisfied), the information received (informat), the willingness of the staff (willingn), the office hours (officeho), the competence of the staff (compete) and the global satisfaction (global).

data(univer, package = "CUB")
str(univer)
#> 'data.frame':    2179 obs. of  12 variables:
#>  $ faculty : int  1 1 1 1 1 1 1 1 1 1 ...
#>  $ freqserv: int  0 0 1 1 0 0 1 0 0 0 ...
#>  $ age     : int  20 21 22 23 21 22 21 22 20 21 ...
#>  $ gender  : int  0 0 0 0 0 1 0 0 1 0 ...
#>  $ diploma : int  2 2 5 6 6 2 6 1 2 2 ...
#>  $ residenc: int  3 2 3 3 1 2 1 2 2 2 ...
#>  $ changefa: int  0 0 0 0 1 0 0 0 0 1 ...
#>  $ informat: int  5 6 6 7 5 1 1 5 6 5 ...
#>  $ willingn: int  6 7 6 7 5 7 2 5 7 6 ...
#>  $ officeho: int  7 5 6 6 4 2 2 3 6 5 ...
#>  $ compete : int  5 6 6 7 5 5 2 4 6 5 ...
#>  $ global  : int  7 7 7 7 6 7 1 4 6 6 ...

The covariates are coded as integers: we recode the ones we use as factors (the faculties are anonymous codes in the original data).

univer$Faculty <- factor(sprintf("F%02d", univer$faculty))
univer$Gender  <- factor(univer$gender, levels = 0:1, labels = c("M", "W"))
univer$User    <- factor(univer$freqserv, levels = 0:1, labels = c("occasional", "regular"))
items <- c("informat", "willingn", "officeho", "compete", "global")

From microdata to a MatD

data2MatD() groups the rows by one or more categorical variables and computes, for each group and each item, the distribution of the scores. With support = 1:7 all the distributions share the seven categories of the scale (categories never chosen get a zero frequency), which makes plots and tables easier to read.

by_faculty <- data2MatD(univer, unit = "Faculty", vars = items, support = 1:7)
by_faculty
#> a matrix of discrete distributions
#> 13 rows x 5 columns
#>     informat             willingn             officeho            
#> F01 [m=5.28 s=1.73 k=7]  [m=6.28 s=1.06 k=7]  [m=5.64 s=1.48 k=7] 
#> F02 [m=6.54 s=0.948 k=7] [m=6.57 s=0.871 k=7] [m=6.26 s=1.27 k=7] 
#> F03 [m=5.39 s=1.42 k=7]  [m=6.04 s=1.11 k=7]  [m=5.27 s=1.35 k=7] 
#> F04 [m=5.82 s=1.12 k=7]  [m=6.11 s=1.2 k=7]   [m=5.4 s=1.21 k=7]  
#> F05 [m=6.06 s=0.91 k=7]  [m=6.38 s=0.801 k=7] [m=6.21 s=0.992 k=7]
#> F06 [m=4.43 s=1.7 k=7]   [m=4.99 s=1.69 k=7]  [m=4.31 s=1.7 k=7]  
#> F07 [m=6.05 s=1.07 k=7]  [m=6.37 s=0.931 k=7] [m=4.61 s=1.8 k=7]  
#> F08 [m=5.93 s=1.18 k=7]  [m=6.43 s=0.917 k=7] [m=5.78 s=1.25 k=7] 
#> F09 [m=5.26 s=1.4 k=7]   [m=5.86 s=1.37 k=7]  [m=5.04 s=1.4 k=7]  
#> F10 [m=5.73 s=1.37 k=7]  [m=5.92 s=1.44 k=7]  [m=4.92 s=1.82 k=7] 
#>     compete              global              
#> F01 [m=5.76 s=1.5 k=7]   [m=6.06 s=1.32 k=7] 
#> F02 [m=6.56 s=0.879 k=7] [m=6.55 s=0.917 k=7]
#> F03 [m=5.36 s=1.5 k=7]   [m=5.57 s=1.17 k=7] 
#> F04 [m=5.83 s=1.19 k=7]  [m=5.87 s=1.12 k=7] 
#> F05 [m=6.2 s=0.88 k=7]   [m=6.26 s=0.837 k=7]
#> F06 [m=4.6 s=1.72 k=7]   [m=4.78 s=1.6 k=7]  
#> F07 [m=6.16 s=1.03 k=7]  [m=6.05 s=0.92 k=7] 
#> F08 [m=6.03 s=0.958 k=7] [m=6.19 s=0.833 k=7]
#> F09 [m=5.6 s=1.23 k=7]   [m=5.46 s=1.15 k=7] 
#> F10 [m=5.23 s=1.15 k=7]  [m=5.38 s=0.923 k=7]
#> ... (only the first rows/columns shown)
#> k = number of support values

Groups can be defined by crossing several variables. Very small groups give unreliable distributions: min.n drops the groups with fewer observations than a threshold.

M <- data2MatD(univer, unit = c("Faculty", "Gender"), vars = items,
               support = 1:7, min.n = 10)
dim(M@M)
#> [1] 26  5
get.MatD.stats(M, "n")$mat[1:6, "global"]   # group sizes
#> F01_M F01_W F02_M F02_W F03_M F03_W 
#>    31    19    84    91   127   128

The 26 rows are the faculty-by-gender groups. This table is used in all the vignettes.

Inspecting the data

Each cell is a distributionD object, with the support x, the probabilities p, the cumulative distribution cdf, the number of observations n, the mean m and the standard deviation s.

d <- get.cell.MatD(M, "F02_W", "global")
d
#> Discrete distribution (7 support values, n = 91)
#>  x       p     cdf
#>  1 0.00000 0.00000
#>  2 0.01099 0.01099
#>  3 0.02198 0.03297
#>  4 0.03297 0.06593
#>  5 0.10989 0.17582
#>  6 0.13187 0.30769
#>  7 0.69231 1.00000
#> mean = 6.40659   std = 1.06882
compQ(d, c(0.25, 0.5, 0.75))   # quartiles
#> [1] 6 7 7
compP(d, 5)                    # proportion of scores <= 5
#> [1] 0.1758242

A grid of bar charts shows a part of the table:

plot(M[c("F02_M", "F02_W", "F06_M", "F06_W"), ])

get.MatD.stats() returns a matrix of summary statistics (means, standard deviations, quantiles, skewness, …) of all the cells:

round(get.MatD.stats(M, "mean")$mat[1:6, ], 2)
#>       informat willingn officeho compete global
#> F01_M     5.35     6.19     5.77    5.45   5.87
#> F01_W     5.16     6.42     5.42    6.26   6.37
#> F02_M     6.62     6.65     6.30    6.64   6.71
#> F02_W     6.47     6.49     6.23    6.48   6.41
#> F03_M     5.27     5.97     5.14    5.35   5.54
#> F03_W     5.52     6.12     5.40    5.37   5.59
round(get.MatD.stats(M, "std")$mat[1:6, ], 2)
#>       informat willingn officeho compete global
#> F01_M     1.73     1.23     1.41    1.66   1.50
#> F01_W     1.72     0.67     1.57    1.02   0.87
#> F02_M     0.79     0.75     1.19    0.77   0.68
#> F02_W     1.07     0.97     1.34    0.96   1.07
#> F03_M     1.44     1.11     1.40    1.39   1.18
#> F03_W     1.39     1.10     1.28    1.59   1.16

Other ways of building the data

From a frequency table. Aggregated data often come as counts by group, item and score. long2MatD() reads this long format.

tab <- as.data.frame(table(unit = univer$Faculty, value = univer$global))
tab$variable <- "global"
head(tab)
#>   unit value Freq variable
#> 1  F01     1    1   global
#> 2  F02     1    0   global
#> 3  F03     1    1   global
#> 4  F04     1    2   global
#> 5  F05     1    0   global
#> 6  F06     1   20   global
G <- long2MatD(tab, unit = "unit", variable = "variable", value = "value", freq = "Freq")
G[1:3, ]
#> a matrix of discrete distributions
#> 3 rows x 1 columns
#>     global              
#> F01 [m=6.06 s=1.32 k=6] 
#> F02 [m=6.55 s=0.917 k=6]
#> F03 [m=5.57 s=1.17 k=7] 
#> k = number of support values

Single distributions can be created from probabilities, counts or raw observations:

distributionD(x = 1:5, p = c(0.1, 0.1, 0.2, 0.3, 0.3))
#> Discrete distribution (5 support values)
#>  x   p cdf
#>  1 0.1 0.1
#>  2 0.1 0.2
#>  3 0.2 0.4
#>  4 0.3 0.7
#>  5 0.3 1.0
#> mean = 3.6   std = 1.28062
distributionD(x = 1:5, counts = c(2, 2, 4, 6, 6))
#> Discrete distribution (5 support values, n = 20)
#>  x   p cdf
#>  1 0.1 0.1
#>  2 0.1 0.2
#>  3 0.2 0.4
#>  4 0.3 0.7
#>  5 0.3 1.0
#> mean = 3.6   std = 1.28062
distributionD(c(4, 5, 5, 3, 5, 4, 2))
#> Discrete distribution (4 support values, n = 7)
#>  x       p     cdf
#>  2 0.14286 0.14286
#>  3 0.14286 0.28571
#>  4 0.28571 0.57143
#>  5 0.42857 1.00000
#> mean = 4   std = 1.06904

and arranged in a matrix with MatD(). From histograms: a MatH of the HistDAWass package can be discretized with MatH2MatD(). Finally, MatD2long() exports a MatD as a long data frame, e.g. for plotting with ggplot2 or for saving to a file.

head(MatD2long(M))
#>     row variable x          p        cdf
#> 1 F01_M informat 1 0.09677419 0.09677419
#> 2 F01_M informat 2 0.03225806 0.12903226
#> 3 F01_M informat 3 0.00000000 0.12903226
#> 4 F01_M informat 4 0.00000000 0.12903226
#> 5 F01_M informat 5 0.25806452 0.38709677
#> 6 F01_M informat 6 0.38709677 0.77419355

Next steps

The vignette 2. Basic statistics of discrete distributional data shows how to describe the table (summary statistics of the cells, Wasserstein barycenters, variance, covariance and correlation). The other vignettes cover clustering, principal component analysis and regression.

References

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.