data <- hrahn$data
chars <- hrahn$chars
showcharlist <- function(selchar) {
tmp <- tempfile()
selected <- ifelse(seq_along(chars) %in% selchar, "[X]", "[ ]")
useful <- makeuseful(selchar)
selected[useful] <- "[O]"
write.table(data.frame(selected, seq_along(chars), chars),
file=tmp, quote=FALSE, col.names=FALSE, row.names=FALSE)
file.show(tmp)
}
makeuseful <- function(selchar) { # numbers of potentially useful characters
selrows <- rowSums(data[, selchar, drop=FALSE]) == length(selchar)
sums <- colSums(data[selrows, , drop=FALSE])
seq_len(ncol(data))[sums > 0 & sums < sum(selrows)]
}
makefam <- function(selchar) { # the core function
selrows <- rowSums(data[, selchar, drop=FALSE]) == length(selchar)
row.names(data)[selrows]
}
displayfam <- function(selfam, howmany=12) { # display first "howmany" families
if (is.null(selfam) || length(selfam) == 0) return("None")
lfam <- length(selfam)
if (lfam > howmany) {
dfam <- selfam[seq_len(howmany)]
res <- paste(c(dfam, paste0("and ", lfam-12, " more")), collapse=", ")
} else {
res <- paste(selfam, collapse=", ")
}
res
}
updatechar <- function(old, new) { # add or remove characters
positive <- new[new > 0 & new <= length(chars)]
old <- union(na.omit(old), positive)
negative <- abs(new[new < 0])
setdiff(old, negative)
}
displaydn <- function(num, sym="-") { # display numbers with dashes
if (!is.numeric(num)) stop("Argument must be numeric")
if (length(num) == 1) return(as.character(num))
num <- sort(unique(num))
if (length(num) == 2) return(paste(num, collapse=", "))
num[abs(num - c(num[length(num)], num[-length(num)])) == 1 &
abs(num - c(num[-1], num[1])) == 1] <- "-"
gsub(", (-, )+", sym, paste(num, collapse=", "))
## slightly longer (but concatenates with +1 number):
## cc <- paste0(num, c(ifelse(diff(num) == 1, "-", ""), ""), collapse=", ")
## gsub("-, ", "-", gsub("-, (-*[0-9]+-, )+", "-", cc))
}
displaychar <- function(selchar) {
if (is.null(selchar) || length(selchar) == 0) return("None")
displaydn(selchar)
}
run <- function(howmany=12, selfam=NULL, selchar=NULL) { # interface, recursive function
if (!interactive()) return(cat("Please run in interactive mode\n"))
cat("Results:", displayfam(selfam, howmany=howmany), "\n")
cat("Selected characters:", displaychar(selchar), "\n")
cat("Potentially useful characters:", displaychar(makeuseful(selchar)), "\n")
cat("===\n")
cat("Type (character) numbers, separate with comma, negative numbers remove from selection\n")
cat("Type 'c' to see the list of characters, [X] selected, [O] potentially useful\n")
cat("Type any other single letter to exit\n")
cat("===\n")
x <- readline(prompt="Your choice: ")
while (TRUE) {
if (x == "c") showcharlist(selchar)
if (x %in% c(letters[-3], LETTERS)) break
new <- suppressWarnings(as.integer(strsplit(x, split=",")[[1]]))
selchar <- updatechar(selchar, new)
selfam <- makefam(selchar)
run(howmany=howmany, selfam=selfam, selchar=selchar)
break
}
}
run()
Run the code above in your browser using DataLab