Skip to content

Commit a03c537

Browse files
committed
- added new vignettes
- bugfixes
1 parent c867531 commit a03c537

File tree

581 files changed

+24747
-1308
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

581 files changed

+24747
-1308
lines changed

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ Imports:
3232
DT,
3333
future,
3434
haven,
35-
readr,
3635
mice (>= 3.2.0),
3736
tibble,
3837
purrr,
@@ -47,9 +46,10 @@ Suggests:
4746
testthat,
4847
shinytest,
4948
lme4,
50-
roxygen2
49+
roxygen2,
50+
qualtRics
5151
Encoding: UTF-8
5252
LazyData: true
53-
RoxygenNote: 6.0.1
53+
RoxygenNote: 6.1.0
5454
Roxygen: list(markdown = TRUE)
5555
VignetteBuilder: knitr

NAMESPACE

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
S3method(as_factor,default)
34
S3method(print,knit_asis)
45
S3method(summary,labelled)
56
S3method(summary,labelled_spss)
67
S3method(zap_attributes,data.frame)
78
S3method(zap_attributes,default)
9+
S3method(zap_label,data.frame)
10+
S3method(zap_label,default)
11+
S3method(zap_labelled,data.frame)
12+
S3method(zap_labelled,labelled)
13+
export("var_label<-")
814
export(aggregate_and_document_scale)
915
export(as_factor)
1016
export(asis_knit_child)
@@ -21,6 +27,8 @@ export(detect_missings)
2127
export(detect_scales)
2228
export(ended)
2329
export(expired)
30+
export(has_label)
31+
export(has_labels)
2432
export(knit_print.alpha)
2533
export(knit_print.htest)
2634
export(knit_print.multilevel)
@@ -36,9 +44,13 @@ export(paste.knit_asis)
3644
export(plot_labelled)
3745
export(rescue_attributes)
3846
export(reverse_labelled_values)
47+
export(var_label)
3948
export(zap_attributes)
4049
export(zap_label)
50+
export(zap_labelled)
4151
import(miniUI)
4252
import(rstudioapi)
4353
import(shiny)
4454
importFrom(haven,as_factor)
55+
importFrom(labelled,"var_label<-")
56+
importFrom(labelled,var_label)

NEWS.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
1-
# codebook 0.6.0
1+
# codebook 0.6.3
2+
## Additions
3+
- Vignettes for
4+
- documenting the expected attribute structure, how to add metadata in R
5+
- importing metadata from SPSS or Stata files
6+
- importing metadata from Qualtrics as made available by `qualtRics` package
7+
- Importing some functions from labelled package to add metadata
8+
- Default method for haven::as_factor when labelled class is absent
9+
10+
## Changes
11+
- Changed the scale summary, so that Likert plots and distributions are shown
12+
on the first tab. Reliability now hidden under "Reliability details".
13+
- removed unnecessary `readr` dependency.
14+
15+
## Bugfixes
16+
- summarising factors in a table
17+
- turning off components of the codebook without empty strings being echoed
18+
- allow using variable and value labels in the absence of the labelled class
19+
(as imported by rio for example)
20+
21+
# codebook 0.6.2
222
## Additions
323
- Three RStudio Addin Shinyapps to browse variable labels and codebook.
424

R/codebook.R

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,16 @@ attribute_summary <- function(var) {
435435
}
436436
}
437437
}
438-
if (exists("labels", x)) {
438+
if (exists("levels", x)) {
439+
x$value_labels <- paste(paste0(seq_len(length(x$levels)), ". ", x$levels),
440+
collapse = ",\n")
441+
x$levels <- NULL
442+
# remove extremely deep qualtrics choices attributes
443+
if (exists("item", x) && exists("choices", x$item)
444+
&& exists("variableName", x$item$choices[[1]])) {
445+
x$item$choices <- NULL
446+
}
447+
} else if (exists("labels", x)) {
439448
if (!is.null(names(x$labels))) {
440449
x$value_labels <- paste(paste0(x$labels, ". ", names(x$labels)),
441450
collapse = ",\n")

R/correct_attributes.R

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -262,63 +262,55 @@ zap_attributes.data.frame <- function(x, attributes = NULL) {
262262
#' Modelled on [haven::zap_labels()], zaps variable labels (not value labels).
263263
#'
264264
#' @param x the data frame or variable
265+
#'
265266
#' @export
267+
#' @examples
268+
#' x <- haven::labelled(rep(1:5, each = 1), c(Bad = 1, Good = 5))
269+
#' zap_label(x)
266270
zap_label <- function(x) {
267271
UseMethod("zap_label")
268272
}
273+
274+
#' @export
269275
zap_label.data.frame <- function(x) {
270276
x[] <- lapply(x, zap_label)
271277
x
272278
}
279+
280+
#' @export
273281
zap_label.default <- function(x) {
274282
attr(x, "label") <- NULL
275283
x
276284
}
277285

278286

279-
280-
#' Aggregate variables and remember which variables this were
287+
#' Zap labelled class
281288
#'
282-
#' The resulting variables will have the attribute `scale_item_names` containing
283-
#' the basis for aggregation. Its `label` attribute will refer to the common stem of the
284-
#' aggregated variable names (if any), the number of variables, and the
285-
#' aggregation function.
289+
#' Modelled on [haven::zap_labels()], zaps labelled class (not other attributes).
286290
#'
287-
#' @param items data.frame of the items that should be aggregated
288-
#' @param fun aggregation function, defaults to rowMeans with na.rm = FALSE
289-
#' @param stem common stem for the variables, specify if it should not be auto-detected
290-
#' as the longest common stem of the variable names
291+
#' @param x the data frame or variable
291292
#' @export
292-
#' @examples
293-
#' testdf <- data.frame(bfi_neuro_1 = rnorm(20), bfi_neuro_2 = rnorm(20),
294-
#' bfi_neuro_3R = rnorm(20), age = rpois(20, 30))
295-
#' item_names <- c('bfi_neuro_1', 'bfi_neuro_2', 'bfi_neuro_3R')
296-
#' testdf$bfi_neuro <- aggregate_and_document_scale(testdf[, item_names])
297-
#' testdf$bfi_neuro
298-
aggregate_and_document_scale <- function(items, fun = rowMeans, stem = NULL) {
299-
new_scale <- fun(items)
300-
item_names <- names(items)
301-
attributes(new_scale)$scale_item_names <- item_names
293+
zap_labelled <- function(x) {
294+
UseMethod("zap_labelled")
295+
}
302296

303-
# find longest common stem
304-
if (is.null(stem)) {
305-
max_len <- min(nchar(item_names))
306-
for (l in max_len:0) {
307-
stem <- unique(stringr::str_sub(item_names, 1, l))
308-
if (length(stem) == 1) break
309-
}
310-
}
311-
# string trimming for idiots
312-
if (nchar(stem)) {
313-
stem <- stringr::str_match(stem, "^(.+?)_?$")[, 2]
314-
}
297+
#' @export
298+
zap_labelled.data.frame <- function(x) {
299+
x[] <- lapply(x, zap_labelled)
300+
x
301+
}
315302

316-
attributes(new_scale)$label <- paste(ncol(items), stem, "items aggregated by",
317-
deparse(substitute(fun)))
318-
new_scale
303+
#' @export
304+
zap_labelled.labelled <- function(x) {
305+
if (inherits(x, "labelled")) {
306+
unclass(x)
307+
} else {
308+
x
309+
}
319310
}
320311

321312

313+
322314
#' Reverse labelled values
323315
#' reverse the underlying valus for a numeric [haven::labelled()] vector while keeping the labels correct
324316
#'
@@ -333,6 +325,14 @@ reverse_labelled_values <- function(x) {
333325
labels <- attributes(x)$labels
334326
values <- unname(labels)
335327
labels <- names(labels)
328+
if (
329+
sum(!is.na(values)) == 0 ||
330+
(any(x > max(values, na.rm = TRUE) |
331+
x < min(values, na.rm = TRUE), na.rm = TRUE))) {
332+
warning(deparse(substitute(x)), ": There are values outside the ",
333+
"labelled range. Reversion will only work if both the minimum ",
334+
"and maximum of the range are part of the responses.")
335+
}
336336
if (length(values) < length(unique(x)) ) {
337337
# if only some values have labels (e.g. extremes), make sure we include all
338338
possible_replies <- union(values, unique(x))
@@ -349,6 +349,7 @@ reverse_labelled_values <- function(x) {
349349
length(range)) {
350350
possible_replies <- range
351351
}
352+
352353
possible_replies <- sort(possible_replies)
353354
recode_replies <- stats::setNames(
354355
as.list(possible_replies), rev(possible_replies))

R/create_metadata.R

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,54 @@
22
#' @export
33
haven::as_factor
44

5+
#' @importFrom labelled var_label
6+
#' @export
7+
labelled::var_label
8+
9+
#' @importFrom labelled var_label<-
10+
#' @export
11+
labelled::`var_label<-`
12+
13+
14+
15+
#' Aggregate variables and remember which variables this were
16+
#'
17+
#' The resulting variables will have the attribute `scale_item_names` containing
18+
#' the basis for aggregation. Its `label` attribute will refer to the common stem of the
19+
#' aggregated variable names (if any), the number of variables, and the
20+
#' aggregation function.
21+
#'
22+
#' @param items data.frame of the items that should be aggregated
23+
#' @param fun aggregation function, defaults to rowMeans with na.rm = FALSE
24+
#' @param stem common stem for the variables, specify if it should not be auto-detected
25+
#' as the longest common stem of the variable names
26+
#' @export
27+
#' @examples
28+
#' testdf <- data.frame(bfi_neuro_1 = rnorm(20), bfi_neuro_2 = rnorm(20),
29+
#' bfi_neuro_3R = rnorm(20), age = rpois(20, 30))
30+
#' item_names <- c('bfi_neuro_1', 'bfi_neuro_2', 'bfi_neuro_3R')
31+
#' testdf$bfi_neuro <- aggregate_and_document_scale(testdf[, item_names])
32+
#' testdf$bfi_neuro
33+
aggregate_and_document_scale <- function(items, fun = rowMeans, stem = NULL) {
34+
new_scale <- fun(items)
35+
item_names <- names(items)
36+
attributes(new_scale)$scale_item_names <- item_names
37+
38+
# find longest common stem
39+
if (is.null(stem)) {
40+
max_len <- min(nchar(item_names))
41+
for (l in max_len:0) {
42+
stem <- unique(stringr::str_sub(item_names, 1, l))
43+
if (length(stem) == 1) break
44+
}
45+
}
46+
# string trimming for idiots
47+
if (nchar(stem)) {
48+
stem <- stringr::str_match(stem, "^(.+?)_?$")[, 2]
49+
}
50+
51+
attributes(new_scale)$label <- paste(ncol(items), stem, "items aggregated by",
52+
deparse(substitute(fun)))
53+
new_scale
54+
}
55+

R/misc.R

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,43 @@ summary.labelled <- function(object, ...) {
167167
summary.labelled_spss <- function(object, ...) {
168168
summary(haven::as_factor(object, levels = "both"), ...)
169169
}
170+
171+
172+
173+
#' Has label
174+
#'
175+
#'
176+
#' @param x a vector
177+
#'
178+
#' @export
179+
#' @examples
180+
#' example("labelled", "haven")
181+
#' has_label(x)
182+
has_label <- function(x) {
183+
haven::is.labelled(x) ||
184+
!is.null(attr(x, 'label')) ||
185+
!is.null(attr(x, 'labels'))
186+
}
187+
188+
189+
#' Has labels
190+
#'
191+
#'
192+
#' @param x a vector
193+
#'
194+
#' @export
195+
#' @examples
196+
#' example("labelled", "haven")
197+
#' has_labels(x)
198+
has_labels <- function(x) {
199+
haven::is.labelled(x) ||
200+
!is.null(attr(x, 'labels'))
201+
}
202+
203+
#' @export
204+
as_factor.default <- function(x,
205+
levels = c("default", "labels", "values", "both"),
206+
ordered = FALSE, ...) {
207+
class(x) <- c("labelled", class(x))
208+
haven::as_factor(x, levels, ordered, ...)
209+
}

R/plot_helpers.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ plot_labelled <- function(item, item_name = NULL,
7171
nonmissing_choices <- attributes(item_nomiss)[["labels"]]
7272
has_labelled_missings <- length(nonmissing_choices) < length(choices)
7373
if (all(is.na(item_nomiss))) {
74-
if (haven::is.labelled(item)) {
75-
item <- haven::as_factor(item, "both")
74+
if (has_labels(item)) {
75+
item <- as_factor(item, "both")
7676
} else {
7777
item <- factor(item, exclude = NULL)
7878
}
@@ -88,7 +88,7 @@ plot_labelled <- function(item, item_name = NULL,
8888
# * factor -> discrete
8989
# * double/integer -> continuous, with binning
9090

91-
if (haven::is.labelled(item)) {
91+
if (has_labels(item)) {
9292
# for labelled values, make labels look proper
9393
label_how <- "both"
9494
if (length(choices)) {
@@ -142,7 +142,7 @@ plot_labelled <- function(item, item_name = NULL,
142142
if (any(names(choices) != choices)) {
143143
label_how <- "both"
144144
}
145-
item <- haven::as_factor(item, levels = label_how)
145+
item <- as_factor(item, levels = label_how)
146146

147147
dist_plot <- ggplot2::ggplot(mapping = ggplot2::aes(x = item)) +
148148
ggplot2::geom_bar() +

_pkgdown.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ reference:
2828
- '`rescue_attributes`'
2929
- '`aggregate_and_document_scale`'
3030
- '`reverse_labelled_values`'
31+
- '`has_label`'
32+
- '`has_labels`'
3133
- title: Prepare data for non-codebook stuff
3234
desc: Functions to remove attributes that might confuse other packages
3335
contents:
3436
- '`zap_attributes`'
3537
- '`zap_label`'
38+
- '`zap_labelled`'
3639
- title: Functions for rmarkdown partials
3740
desc: Make rmarkdown partials whether in interactive mode or not
3841
contents:

docs/CONDUCT.html

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

0 commit comments

Comments
 (0)