Skip to content

Commit

Permalink
Merge pull request #43 from Jean-Baptiste-Camps/dev
Browse files Browse the repository at this point in the history
Version 0.3.0
  • Loading branch information
floriancafiero authored May 22, 2018
2 parents 0a7910b + 7ea158e commit e089c1a
Show file tree
Hide file tree
Showing 73 changed files with 3,316 additions and 1,189 deletions.
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
\.Rhistory
\.gitignore
\.git
version_history
deprec
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
.Rhistory
inst/doc
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ language: R
sudo: false
cache: packages

warnings_are_errors: false #Modify once warnings are solved. Added temporarily 20171025
# warnings_are_errors: false #Modify once warnings are solved. Added temporarily 20171025
r_check_args: --as-cran

after_success:
- Rscript -e 'covr::codecov()'
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Package: stemmatology
Type: Package
Title: An R Stemmatology Package
Version: 0.2.3
Date: 2018-05-04
Version: 0.3.0
Date: 2018-05-20
Author: Jean-Baptiste Camps ; Florian Cafiero
Maintainer: Jean-Baptiste Camps <jbcamps@hotmail.com>
Description: Build and analyse the genealogy of textual or musical traditions.
BugReports: https://github.com/Jean-Baptiste-Camps/stemmatology/issues
Imports: graphics, stats, utils, network, sna, cluster, igraph
Imports: graphics, stats, cluster, igraph, xml2
Suggests:
testthat,
knitr,
Expand Down
13 changes: 7 additions & 6 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
exportPattern("^[[:alpha:]]+")
importFrom("graphics", "axis", "barplot", "legend", "par", "plot","title")
exportPattern("^[^\\.]") # This exports everything from stemmatology
# namespace that does not start with a dot. If at some point we
# want a more explicit listing, we might use export(PCC, PCC.Exploratory…)
importFrom("graphics", "axis", "barplot", "plot","title")
# It would be possible to remove stats import with a few modifications (only 2 uses)
importFrom("stats", "fisher.test", "na.omit")
importFrom("utils", "read.csv")
importFrom("sna", "gplot", "gplot.layout.fruchtermanreingold")
importFrom("network", "as.network", "network.vertex.names", "as.matrix.network", "set.vertex.attribute", "get.vertex.attribute")
importFrom("cluster", "pam")
importFrom("igraph", "graph_from_edgelist", "layout_as_tree", "plot.igraph", "E", "union", "topo_sort","V","neighbors")
importFrom("igraph", "graph_from_edgelist", "layout_as_tree", "layout_with_fr", "plot.igraph", "E", "union", "topo_sort","V","neighbors", "as_adjacency_matrix")
importFrom("xml2", "read_xml", "xml_ns_strip", "xml_find_all", "xml_text")
20 changes: 0 additions & 20 deletions R/Import.TEIApparatus.R

This file was deleted.

164 changes: 111 additions & 53 deletions R/PCC.Exploratory.R
Original file line number Diff line number Diff line change
@@ -1,91 +1,149 @@
PCC.Exploratory <-
function(x, omissionsAsReadings = FALSE, alternateReadings = FALSE, pauseAtPlot = FALSE,
interactive = TRUE) {
# TODO(JBC): dans ce groupe de fonction, comme dans le précédent, il est
# impératif de tester que les options font bien leur job (y compris en
# étant passées aux sous-fonctions) This is the global function for
# exploratory methods of the PCC type. In entry, a matrix with a column
# per witness, and a row per variant location, with readings coded
# with numbers. TODO(JBC): une version prenant en compte interactive =
# FALSE, pour tout faire d'elle-même avec des valeurs moyennes (pas pour
function(x,
omissionsAsReadings = FALSE,
alternateReadings = FALSE,
pauseAtPlot = FALSE,
ask = TRUE,
threshold = NULL,
verbose = FALSE
) {
# This is the global function for exploratory methods of the PCC type.
# In entry, a matrix with a column per witness, and a row per variant location,
# with readings coded with numbers.
# TODO(JBC): une version prenant en compte ask = FALSE,
# pour tout faire d'elle-même avec des valeurs moyennes (pas pour
# tout de suite) - ou demander à l'utilisateur de les choisir plutôt
# que de proposer des valeurs par défaut risquées
if (!is.matrix(x)) {
stop("Input must be a matrix.")
stop("Input must be a matrix.")
}
if (ask == FALSE & is.null(threshold)){
stop("you must specify threshold with ask = FALSE")
}
tableVariantes = x
pccConflicts = PCC.conflicts(tableVariantes, omissionsAsReadings = omissionsAsReadings, alternateReadings = alternateReadings) # Simple interaction, which tests for value inputed by the user
answered = FALSE
while (answered == FALSE) {
pccConflicts = PCC.conflicts(tableVariantes,
omissionsAsReadings = omissionsAsReadings,
alternateReadings = alternateReadings)
# If there are no conflicts, output directly
if (sum(pccConflicts$conflictsTotal[, 1]) == 0) {
return(pccConflicts)
}
# Simple interaction, which tests for value inputed by the user
if(ask == TRUE){
answered = FALSE
while (answered == FALSE) {
answerOne = readline("Do you want to proceed to the analysis of the network conflictuality ? Y/N \n ")
if (answerOne != "N" && answerOne != "Y") {
print("Please enter Y (yes) or N (no).")
print("Please enter Y (yes) or N (no).")
}
if (answerOne == "N") {
return(pccConflicts)
return(pccConflicts)
}
if (answerOne == "Y") {
answered = TRUE
answered = TRUE
}
}
}
answered = FALSE
while (answered == FALSE) {
pccOverconflicting = PCC.overconflicting(pccConflicts)
writeLines("Are you satisfied with this configuration and do you want to\n Proceed to actual elimination of over-conflicting variant locations [P],\n Try again with different value [T],\n or Quit [Q] ? \n ")
if(ask){
answered = FALSE
while (answered == FALSE) {
pccOverconflicting = PCC.overconflicting(pccConflicts, ask = ask, threshold = threshold)
writeLines(
"Are you satisfied with this configuration and do you want to\n Proceed to actual elimination of over-conflicting variant locations [P],\n Try again with different value [T],\n or Quit [Q] ? \n "
)
reiterateQuestion = TRUE
while (reiterateQuestion == TRUE) {
answerOne = readline("(P/T/Q)")
if (answerOne != "P" && answerOne != "T" && answerOne != "Q") {
print("Please enter P (Proceed), T (Try again) or Q (Quit).")
}
if (answerOne == "T") {
reiterateQuestion = FALSE
}
if (answerOne == "Q") {
return(pccOverconflicting)
}
if (answerOne == "P") {
reiterateQuestion = FALSE
answered = TRUE
}
answerOne = readline("(P/T/Q)")
if (answerOne != "P" &&
answerOne != "T" && answerOne != "Q") {
print("Please enter P (Proceed), T (Try again) or Q (Quit).")
}
if (answerOne == "T") {
reiterateQuestion = FALSE
}
if (answerOne == "Q") {
return(pccOverconflicting)
}
if (answerOne == "P") {
reiterateQuestion = FALSE
answered = TRUE
}
}
}
} else{
pccOverconflicting = PCC.overconflicting(pccConflicts, ask = ask, threshold = threshold)
}
pccElimination = PCC.elimination(pccOverconflicting)
pccConflicts = PCC.conflicts(pccElimination, omissionsAsReadings = omissionsAsReadings, alternateReadings = alternateReadings)
pccConflicts = PCC.conflicts(pccElimination,
omissionsAsReadings = omissionsAsReadings,
alternateReadings = alternateReadings)
if (sum(pccConflicts$conflictsTotal[, 1]) == 0) {
print("There is no longer any conflict in the database. Function will stop.")
return(pccConflicts)
if(verbose){
cat("There is no longer any conflict in the database. Function will stop.")
}
return(pccConflicts)
}
message = paste("There is still ", nrow(pccConflicts$edgelist), "conflicts in the database. If this number is high it might indicate that : \n 1. The conflictuality index chosen was too low. \n 2. There are concurring structures in the tradition (due for instance to contamination).")
writeLines(message)
answered = FALSE
while (answered == FALSE) {
if(ask){
cat(
"There is still ",
nrow(pccConflicts$edgelist),
"conflicts in the database.\n",
"If this number is high it might indicate that: \n",
"1. The conflictuality index chosen was too low.\n",
"2. There are concurring structures in the tradition (due for instance to contamination)."
)
answered = FALSE
while (answered == FALSE) {
answerOne = readline("Do you want to proceed to contamination detection methods ? Y/N \n ")
if (answerOne != "N" && answerOne != "Y") {
print("Please enter Y (yes) or N (no).")
print("Please enter Y (yes) or N (no).")
}
if (answerOne == "N") {
return(pccConflicts)
return(pccConflicts)
}
if (answerOne == "Y") {
answered = TRUE
answered = TRUE
}
}
}
pccContam = PCC.contam(pccConflicts, pauseAtPlot = pauseAtPlot, omissionsAsReadings = omissionsAsReadings, alternateReadings = alternateReadings)
print(pccContam$conflictsDifferences)
answered = FALSE
while (answered == FALSE) {
pccContam = PCC.contam(
pccConflicts,
pauseAtPlot = pauseAtPlot,
omissionsAsReadings = omissionsAsReadings,
alternateReadings = alternateReadings
)
if(ask){
print(pccContam$conflictsDifferences)
answered = FALSE
while (answered == FALSE) {
answerOne = readline("Do you want to define alternate configurations for stemma building ? Y/N \n ")
if (answerOne != "N" && answerOne != "Y") {
print("Please enter Y (yes) or N (no).")
print("Please enter Y (yes) or N (no).")
}
if (answerOne == "N") {
return(pccContam)
return(pccContam)
}
if (answerOne == "Y") {
answered = TRUE
answered = TRUE
pccEquipollent = PCC.equipollent(pccConflicts, ask = ask, verbose = verbose)
return(pccEquipollent)
}
}
}
# and now, in the ask = FALSE mode, we will try to decide smartly for the user
# Either, there are one or several wits responsible for conficts, and
# we will equipollent for them, or, otherwise, we will try to do it
# on a global basis
myWits = rownames(pccContam$conflictsDifferences[
pccContam$conflictsDifferences + (sum(pccContam$totalByMs[,1]) / 2)
== 0, , drop = FALSE
])
if(is.null(myWits)){
pccEquipollent = PCC.equipollent(pccConflicts, ask = ask, scope = 'T',
verbose = verbose)
} else {
pccEquipollent = PCC.equipollent(pccConflicts, ask = ask, scope = 'W',
wits = myWits, verbose = verbose)
}
pccEquipollent = PCC.equipollent(pccConflicts)
return(pccEquipollent)
}
}
95 changes: 61 additions & 34 deletions R/PCC.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,73 @@
recoverNAs = TRUE,
layout_as_stemma = FALSE,
pauseAtPlot = FALSE,
interactive = TRUE) {

ask = TRUE,
threshold = NULL,
verbose = FALSE) {
# Global shell for the PCC functions. Successively calls PCC.Exploratory
# and PCC.Stemma on the dataset NB: TODO(JBC) this function should be
# updated when we will have defined appropriate object classes for the
# various functions, and harmonised them.
pccExploratory = PCC.Exploratory(x, omissionsAsReadings = omissionsAsReadings, alternateReadings = alternateReadings, pauseAtPlot = pauseAtPlot, interactive = interactive)
# and PCC.Stemma on the dataset
pccExploratory = PCC.Exploratory(
x,
omissionsAsReadings = omissionsAsReadings,
alternateReadings = alternateReadings,
pauseAtPlot = pauseAtPlot,
ask = ask,
threshold = threshold,
verbose = verbose
)
# Here, we will need to have appropriate version of the command for the
# various outputs of PCC.Exploratory if is.pccOverconflicting
if (is.matrix(pccExploratory)) {
# What does this do?
output = pccStemma(pccExploratory)
#TODO: What does this do?
output = pccStemma(pccExploratory)
} else {
if (!is.matrix(pccExploratory)) {
# if is.pccConflicts|pccOverconflicting|pccContam (with no alternate yet)
if (class(pccExploratory) == "pccConflicts"
| class(pccExploratory) == "pccOverconflicting"
| class(pccExploratory) == "pccContam") {
output = PCC.Stemma(pccExploratory$database, limit = limit, recoverNAs = recoverNAs, layout_as_stemma = layout_as_stemma)
} else {
# if is.pccEquipollent
if (class(pccExploratory) == "pccEquipollent") {
if(is.null(pccExploratory$databases)){
stop("It does not make sense to try to build a stemma on a presumably contaminated tradition if you did not define alternative configurations (using PCC.equipollent)")
}
output = as.list(NULL)
for (i in 1:length(pccExploratory$databases)) {
pccStemma = PCC.Stemma(pccExploratory$databases[[i]], limit = limit, recoverNAs = recoverNAs, layout_as_stemma = layout_as_stemma)
graphics::title(sub = paste("Alternative stemma", i, "out of",
length(pccExploratory$databases)))
if (i < length(pccExploratory$databases)) {
readline("Press enter to proceed to next alternative stemma")
}
output[[i]] = pccStemma
}
} else {
stop("Input is unknown.")
}
if (!is.matrix(pccExploratory)) {
# if is.pccConflicts|pccOverconflicting|pccContam (with no alternate yet)
if (class(pccExploratory) == "pccConflicts"
| class(pccExploratory) == "pccOverconflicting"
| class(pccExploratory) == "pccContam") {
output = PCC.Stemma(
pccExploratory$database,
limit = limit,
recoverNAs = recoverNAs,
layout_as_stemma = layout_as_stemma,
ask = ask,
verbose = verbose
)
} else {
# if is.pccEquipollent
if (class(pccExploratory) == "pccEquipollent") {
if (is.null(pccExploratory$databases)) {
stop(
"It does not make sense to try to build a stemma on a presumably contaminated tradition if you did not define alternative configurations (using PCC.equipollent)"
)
}
output = as.list(NULL)
for (i in 1:length(pccExploratory$databases)) {
pccStemma = PCC.Stemma(
pccExploratory$databases[[i]],
limit = limit,
recoverNAs = recoverNAs,
layout_as_stemma = layout_as_stemma,
ask = ask,
verbose = verbose
)
graphics::title(sub = paste(
"Alternative stemma",
i,
"out of",
length(pccExploratory$databases)
))
if (pauseAtPlot && i < length(pccExploratory$databases)) {
readline("Press enter to proceed to next alternative stemma")
}
output[[i]] = pccStemma
}
} else {
stop("Input is unknown.")
}
}
}
}
return(output)
}
}
1 change: 1 addition & 0 deletions R/PCC.buildGroup.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function(x, limit = 0, ask = TRUE) {
# And here, we add a final test to check if there are unvalid
# configurations in which some members are in conflict between
# themselves, in which case we will remove them.
# TODO: improve this !
toBeRemovedAsWell = as.vector(NULL)
for (l in seq_len(length(groups))) {
# We look in the severe desagreement table for all witnesses
Expand Down
Loading

0 comments on commit e089c1a

Please sign in to comment.