#' Percent Inter-Rater Reliabilitiy
#'
#' Percent inter-rater reliabilitiy by variable.
#'
#' @param meta.obj.1 An MDlist (an object from \code{read.MD}) for time 1
#' (primary coding).
#' @param meta.obj.2 An MDlist (an object from \code{read.MD}) for time 2
#' (secondary coding).
#' @param exclude.vars A character vector of variables to exclude from reliability
#' check.
#' @param cor.var An optional argument for the MDlist variable that is a list of
#' correlation matrices (can detect and handle correlation variables that are in
#' character correlation triangle format).
#' @param comp.var The variable to compare for discrepencies between the two MDlists.
#' Default is "coder". This argument is particularly useful when there are more
#' than two coders.
#' @param file Optional connection, or a character string naming the file to print to.
#' @param order.by.comp.var logical. If TRUE orders the study disagreements by the
#' comparison variable.
#' @return Returns a list:
#' \item{Variable_Agreement_Rate}{A dataframe of percentage agreement/disagreement
#' for each variable. Final row is overall agreement rate.}
#' \item{Disagreements}{A list of disagreements of study variables between comparison
#' groups (time 1 and time 2) per study. If correlations are being compared the
#' function outputs an agreement matrix. Agreement is marked as \code{-} and
#' disagreement as \code{X}.}
#' @note This function assumes double coding, that is all studies have been coded by
#' two different coders.
#' @keywords inter-rater reliability
#' @export
#' @examples
#' path <- system.file("extdata/bibTest.bib", package = "metaDAT")
#' dat1 <- read.MD(path)
#' path2 <- system.file("extdata/bibTest2.bib", package = "metaDAT")
#' dat2 <- read.MD(path2)
#' MD_IRR(dat1, dat2, cor.var = "correlation_triangle")
#' # MD_IRR(dat1, dat2, cor.var = "correlation_triangle", file = "foo.txt")
#' # unlink("foo.txt", recursive = TRUE, force = FALSE) #delete previous file
MD_IRR <- function(meta.obj.1, meta.obj.2, exclude.vars = c("author", "ID", "time"),
cor.var = NULL, comp.var = "coder", file = NULL, order.by.comp.var = TRUE) {
metas <- list(meta.obj.1, meta.obj.2)
studs <- lapply(metas, function(x) sort(names(x)))
if (!all(studs[[1]] == studs[[2]])) {
stop("Study names for meta.obj.1 & meta.obj.2 do not correspond.")
}
vars <- unique(unlist(lapply(metas, MDnames)))
vars <- vars[!vars %in% c(exclude.vars, comp.var, cor.var)]
output <- invisible(lapply(vars, function(x) {
var1 <- MDget(metas[[1]], vars = x, s.names = TRUE)
var2 <- MDget(metas[[2]], vars = x, s.names = TRUE)
comps <- unlist(lapply(seq_along(var1), function(i) {
identical(var1[i], var2[i])
}))
agree <- 100 * round(sum(comps)/length(comps), 4)
list(agree = agree, disagree = 100 - agree, raw = comps)
}))
names(output) <- vars
rates <- lapply(output, "[", 1:2)
raws <- unlist(lapply(output, "[", 3), recursive = FALSE)
names(raws) <- gsub(".raw", "", names(raws))
if(!is.null(cor.var)) {
cors <- invisible(lapply(metas, function(x) {
MDget(x, vars = cor.var, s.names = TRUE)
}))
type <- rapply(cors, class) %in% c("matrix", "full_matrix", "incomplete_matrix")
if (sum(type) == 0) {
cors <- lapply(cors, function(x) lapply(x, MDlist2matrix))
} else {
if (sum(type) == length(cors)) {
cors <- cors
} else {
stop("different matrix types supplied to cor.var")
}
}
vect.list <- invisible(lapply(cors, function(x) lapply(x, matrix2vectors)))
vect.list <- invisible(lapply(vect.list, function(x) lapply(x, function(z) {
z[, "vars"] <- paste2(z[, 1:2], sep = "_")
z
})))
cor.agree <- invisible(lapply(seq_along(vect.list[[1]]), function(i){
mvar <- merge(vect.list[[1]][[i]], vect.list[[2]][[i]][, 3:4], "vars")
cor.ag <- invisible(sapply(1:nrow(mvar), function(i) {
identical(mvar[i, 4], mvar[i, 5])
}))
names(cor.ag) <- mvar[, 1]
mvar[, "agree"] <- cor.ag
mvar[, "agree2"] <- ifelse(cor.ag, "-", "X")
mvar
}))
names(cor.agree) <- studs[[1]]
agree.mats <- invisible(lapply(cor.agree, function(x) {
if (all(x[, 6])) {
return(NULL)
}
z <- vectors2matrix(x[, -c(1, 4:6)])
diag(z) <- "-"
noquote(z)
}))
unagree.cors <- agree.mats[!sapply(agree.mats, is.null)]
agree.logical <- do.call(rbind, cor.agree)[, "agree"]
agree <- 100 * round(sum(agree.logical)/length(agree.logical), 4)
cor.rate <- list(agree = agree, disagree = 100 - agree)
rates[["correlations"]] <- cor.rate
raws[["correlations"]] <- unlist(lapply(cor.agree, "[", 6))
}
rates <- do.call(rbind, rates)
raws <- unlist(raws)
overall <- 100*round(sum(raws)/length(raws), 4)
overall[2] <- 100 - overall
names(overall) <- colnames(rates)
rates <- rbind(rates, overall)
meta.obj.1b <- invisible(lapply(meta.obj.1, function(x) {
keeps <- x[vars]
keeps[!sapply(keeps, is.null)]
}))
meta.obj.2b <- invisible(lapply(meta.obj.2, function(x) {
keeps <- x[vars]
keeps[!sapply(keeps, is.null)]
}))
metas2 <- list(meta.obj.1b, meta.obj.2b)
stud.comp <- invisible(lapply(seq_along(studs[[1]]), function(i) {
x <- metas2[[1]][[i]]
y <- metas2[[2]][[i]]
xdat <- data.frame(vars = names(x), value = unlist(x), row.names=NULL)
ydat <- data.frame(vars = names(y), value = unlist(y), row.names=NULL)
mdat <- merge(xdat, ydat, "vars")
stud.agree <- invisible(sapply(1:nrow(mdat), function(i) {
identical(mdat[i, 2], mdat[i, 3])
}))
names(stud.agree) <- mdat[, 1]
stud.agree <- stud.agree[!stud.agree]
if (identical(unname(stud.agree), logical(0))) {
NULL
} else {
names(stud.agree)
}
}))
names(stud.comp) <- studs[[1]]
stud.comp <- invisible(lapply(stud.comp, function(x) {
if (is.null(x)) {
NULL
} else {
paste(x, collapse = ", ")
}
}))
if(!is.null(cor.var)) {
stud.comp <- invisible(lapply(seq_along(stud.comp), function(i) list(variables = stud.comp[[i]],
correlations = agree.mats[[i]])))
names(stud.comp) <- studs[[1]]
}
if(!is.null(comp.var)) {
nms <- sapply(metas, function(x) MDget(x, comp.var))
comp <- data.frame(studies = studs[[1]], nms)
names(stud.comp) <- paste2(comp, sep="__")
if (order.by.comp.var) {
comp <- comp[order(comp$X1, comp$X2, comp$studies),]
stud.comp <- stud.comp[paste2(comp, sep="__")]
}
}
stud.comp <- stud.comp[!sapply(stud.comp, function(x) {
all(sapply(x, is.null))
})]
stud.comp <- sapply(stud.comp, function(x) {
x[!sapply(x, is.null)]
})
OUT <- list(Variable_Agreement_Rate = rates, Disagreements = stud.comp)
if (!is.null(file)) {
if(!(c(grepl("/", file) & grepl("/", file)))) {
file2 <- paste0(getwd(), "/", file)
} else {
file2 <- file
}
cat("Variable Agreement Rate:\n\n", file = file2)
sink(append = TRUE, file=file2, type = "output")
print(OUT[[1]])
sink()
cat(paste0("\n", paste(rep("=", 50), collapse="")), "\n\n",
file = file2, append = TRUE)
cat("Disagreements:\n\n", file = file2, append = TRUE)
sink(append = TRUE, file = file2, type = "output")
print(OUT[[2]])
sink()
}
OUT
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.