as.bt <- function (df, value = NA) { if (class(df) != "data.frame") stop("Can only convert data frames") facnames <- setdiff(names(df), value) toindx <- function(x) if (is.numeric(x)) unique(x) else if (is.factor(x)) levels(x) else as.character(unique(x)) inds <- lapply(facnames, function(x) toindx(df[, x])) names(inds) <- facnames dims <- sapply(inds, length) dimtot <- prod(dims) vals <- sapply(1:dimtot, function(i) { okrows <- rep(TRUE, nrow(df)) levswanted <- sapply(1:length(facnames), function(j) { nm <- facnames[[j]] nl <- ((i - 1)%/%cumprod(c(1, dims))[j])%%dims[j] lev <- inds[[nm]][nl + 1] okrows <<- okrows & df[, nm] == lev lev }) levs <- paste(facnames, levswanted, sep = "=", collapse = " ") if (!any(okrows)) warning("No entries for ", levs, call. = FALSE) if (length(which(okrows)) > 1) warning("Multiple entries for", levs, call. = FALSE) x <- NA if (!is.na(value)) if (any(okrows)) x <- df[which(okrows)[1], value] if (!is.na(value) & !all(is.na(x)) & !is.numeric(x)) x <- as.character(x) x }) res <- vals class(inds) <- "btindexes" attr(res, "indexes") <- inds class(res) <- "bt" res }