Skip to content

Commit fef841e

Browse files
Merge pull request #58 from R-Computing-Lab/dev_main
1.3.5 update
2 parents d1ae976 + b9be8af commit fef841e

58 files changed

Lines changed: 7369 additions & 321 deletions

Some content is hidden

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

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ CITATION.cff$
2121
^_pkgdown\.yml$
2222
^docs$
2323
^pkgdown$
24+
^\.vscode$

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ tests/testthat/Rplots.pdf
1313
ASOIAF.ged
1414
*.Rproj
1515

16+
.vscode/launch.json
17+
dataRelatedPairs_new2.csv

.lintr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
linters: linters_with_defaults(line_length_linter(120),commented_code_linter = NULL,object_name_linter = object_name_linter(styles = c("snake_case", "symbols"))) # see vignette("lintr")
1+
linters: linters_with_defaults(
2+
line_length_linter = NULL,
3+
commented_code_linter = NULL,
4+
object_name_linter=NULL) # see vignette("lintr")
25
encoding: "UTF-8"

BGmisc.Rproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Version: 1.0
2+
ProjectId: 660dde05-601d-4692-8962-9a2223744832
23

34
RestoreWorkspace: No
45
SaveWorkspace: No

DESCRIPTION

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: BGmisc
22
Title: An R Package for Extended Behavior Genetics Analysis
3-
Version: 1.3.3
3+
Version: 1.3.5
44
Authors@R: c(
55
person("S. Mason", "Garrison", , "garrissm@wfu.edu", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0002-4804-6003")),
@@ -33,8 +33,10 @@ Imports:
3333
kinship2,
3434
Matrix,
3535
stats,
36-
stringr
36+
stringr,
37+
methods
3738
Suggests:
39+
corrplot,
3840
dplyr,
3941
EasyMx,
4042
knitr,

NAMESPACE

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@ export(SimPed)
44
export(allGens)
55
export(calculateRelatedness)
66
export(checkIDs)
7+
export(checkPedigreeNetwork)
78
export(checkSex)
9+
export(com2links)
810
export(comp2vech)
911
export(createGenDataFrame)
1012
export(dropLink)
1113
export(evenInsert)
14+
export(extractSummaryText)
1215
export(famSizeCal)
1316
export(fitComponentModel)
1417
export(identifyComponentModel)
1518
export(inferRelatedness)
1619
export(makeInbreeding)
1720
export(makeTwins)
21+
export(parseTree)
1822
export(ped2add)
1923
export(ped2ce)
2024
export(ped2cn)
@@ -26,6 +30,7 @@ export(ped2mit)
2630
export(ped2paternal)
2731
export(plotPedigree)
2832
export(readGedcom)
33+
export(readWikifamilytree)
2934
export(recodeSex)
3035
export(related_coef)
3136
export(relatedness)

NEWS.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
# BGmisc 1.3.5
2+
* Added ASOIAF pedigree
3+
* Added com2links() function to convert components to kinship links, with accompanying tests
4+
* Added extractWikiFamilyTree() function to parse family trees from wiki templates, with accompanying tests
5+
* Created vignette demonstrating adjacency matrix methods and applications
6+
* Improved plotPedigree() function by silencing unnecessary invisible list outputs
7+
* Added checkPedigreeNetwork() function for validating pedigree network structure, with accompanying tests
8+
9+
# BGmisc 1.3.4.1
10+
* Hot fix to resolve issue with list of adjacency matrix not loading saved version
11+
* Reoptimized generation calculation
12+
13+
# BGmisc 1.3.4
14+
* Added alternative (and faster) methods to create the adjacency matrix
15+
* Add tests for comparison of adjacency matrix build methods
16+
* Added Royal Family pedigree
17+
118
# BGmisc 1.3.3
219
* Added ability to save and reload pedigree objects that are used by ped2Com
320
* Optimized generation calculation

R/buildPedigree.R

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ ped2fam <- function(ped, personID = "ID",
5151
ped2 <- merge(fam, ped,
5252
by = personID, all.x = FALSE, all.y = TRUE
5353
)
54-
5554
return(ped2)
5655
}
5756

R/checkPedigree.R

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#' Validate Pedigree Network Structure
2+
#'
3+
#' Checks for structural issues in pedigree networks, including:
4+
#' - Individuals with more than two parents.
5+
#' - Presence of cyclic parent-child relationships.
6+
#'
7+
#' @param ped Dataframe representing the pedigree.
8+
#' @param personID Character. Column name for individual IDs.
9+
#' @param momID Character. Column name for maternal IDs.
10+
#' @param dadID Character. Column name for paternal IDs.
11+
#' @param verbose Logical. If TRUE, print informative messages.
12+
#'
13+
#' @return List containing detailed validation results.
14+
#' @examples
15+
#' \dontrun{
16+
#' results <- checkPedigreeNetwork(ped, personID = "ID",
17+
#' momID = "momID", dadID = "dadID", verbose = TRUE)
18+
#' }
19+
#' @export
20+
checkPedigreeNetwork <- function(ped, personID = "ID", momID = "momID", dadID = "dadID", verbose = FALSE) {
21+
# Create directed edges from parent to child relationships
22+
ped_edges <- rbind(
23+
data.frame(from = ped[[momID]], to = ped[[personID]]),
24+
data.frame(from = ped[[dadID]], to = ped[[personID]])
25+
)
26+
ped_edges <- ped_edges[!is.na(ped_edges$from) & !is.na(ped_edges$to), ]
27+
28+
ped_graph <- igraph::graph_from_data_frame(ped_edges, directed = TRUE)
29+
30+
results <- list()
31+
32+
## Check for individuals with more than two parents
33+
indegrees <- igraph::degree(ped_graph, mode = "in")
34+
ids_excess_parents <- names(indegrees[indegrees > 2])
35+
36+
results$individuals_with_excess_parents <- ids_excess_parents
37+
38+
if (verbose) {
39+
if (length(ids_excess_parents) > 0) {
40+
message("Individuals with more than two parents detected: ", paste(ids_excess_parents, collapse = ", "))
41+
} else {
42+
message("No individuals with more than two parents detected.")
43+
}
44+
}
45+
46+
## Check for duplicate edges
47+
48+
duplicate_edges_idx <- igraph::which_multiple(ped_graph)
49+
duplicate_edges <- igraph::as_edgelist(ped_graph)[duplicate_edges_idx, , drop = FALSE]
50+
51+
results$duplicate_edges <- duplicate_edges
52+
53+
if (verbose) {
54+
if (nrow(duplicate_edges) > 0) {
55+
message("Duplicate edges detected:")
56+
print(duplicate_edges)
57+
} else {
58+
message("No duplicate edges detected.")
59+
}
60+
}
61+
## Check for cyclic relationships
62+
is_acyclic <- igraph::is_dag(ped_graph)
63+
results$is_acyclic <- is_acyclic
64+
65+
if (!is_acyclic) {
66+
cyclic_edges <- igraph::feedback_arc_set(ped_graph)
67+
cyclic_relationships <- igraph::as_edgelist(ped_graph)[cyclic_edges, ]
68+
results$cyclic_relationships <- cyclic_relationships
69+
if (verbose) {
70+
message("Cyclic relationships detected:")
71+
print(cyclic_relationships)
72+
}
73+
} else {
74+
results$cyclic_relationships <- NULL
75+
if (verbose) message("No cyclic relationships detected.")
76+
}
77+
78+
return(results)
79+
}

R/checkSex.R

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,8 @@ checkSex <- function(ped, code_male = NULL, code_female = NULL, verbose = FALSE,
5353
validation_results$sex_unique <- unique(ped$sex)
5454
validation_results$sex_length <- length(unique(ped$sex))
5555
if (verbose) {
56-
cat(paste0(
57-
validation_results$sex_length, " unique values found.\n ",
58-
paste0(validation_results$sex_unique)
59-
))
56+
cat(paste0(validation_results$sex_length, " unique values found.\n"))
57+
cat(paste0("Unique values: ", paste0(validation_results$sex_unique, collapse = ", "), "\n"))
6058
}
6159
# Are there multiple sexes/genders in the list of dads and moms?
6260

@@ -83,7 +81,6 @@ checkSex <- function(ped, code_male = NULL, code_female = NULL, verbose = FALSE,
8381
remove(df_moms)
8482
}
8583

86-
8784
if (repair) {
8885
if (verbose) {
8986
cat("Step 2: Attempting to repair sex coding...\n")
@@ -99,7 +96,7 @@ checkSex <- function(ped, code_male = NULL, code_female = NULL, verbose = FALSE,
9996
num_changes <- sum(original_ped$sex != ped$sex)
10097
# Record the change and the count
10198
changes[[length(changes) + 1]] <- sprintf(
102-
"Recode sex based on most frequent sex in dads: %s. Total gender changes made: %d",
99+
"Recode sex based on most frequent sex in dads: %s. Total sex changes made: %d",
103100
validation_results$most_frequent_sex_dad, num_changes
104101
)
105102
}
@@ -138,8 +135,8 @@ checkSex <- function(ped, code_male = NULL, code_female = NULL, verbose = FALSE,
138135
#' @export
139136
#'
140137
#' @seealso \code{\link{checkSex}}
141-
repairSex <- function(ped, verbose = FALSE, code_male = NULL) {
142-
checkSex(ped = ped, verbose = verbose, repair = TRUE, code_male = code_male)
138+
repairSex <- function(ped, verbose = FALSE, code_male = NULL, code_female = NULL) {
139+
checkSex(ped = ped, verbose = verbose, repair = TRUE, code_male = code_male, code_female = code_female)
143140
}
144141

145142
#' Recodes Sex Variable in a Pedigree Dataframe
@@ -164,25 +161,24 @@ recodeSex <- function(
164161
if (!is.null(code_na)) {
165162
ped$sex[ped$sex == code_na] <- NA
166163
}
167-
168164
# Recode as "F" or "M" based on code_male, preserving NAs
169-
if (!is.null(code_male) & !is.null(code_female)) {
165+
if (!is.null(code_male) && !is.null(code_female)) {
170166
# Initialize sex_recode as NA, preserving the length of the 'sex' column
171167
ped$sex_recode <- recode_na
172168
ped$sex_recode[ped$sex == code_female] <- recode_female
173169
ped$sex_recode[ped$sex == code_male] <- recode_male
174170
# Overwriting temp recode variable
175171
ped$sex <- ped$sex_recode
176172
ped$sex_recode <- NULL
177-
} else if (!is.null(code_male) & is.null(code_female)) {
173+
} else if (!is.null(code_male) && is.null(code_female)) {
178174
# Initialize sex_recode as NA, preserving the length of the 'sex' column
179175
ped$sex_recode <- recode_na
180176
ped$sex_recode[ped$sex != code_male & !is.na(ped$sex)] <- recode_female
181177
ped$sex_recode[ped$sex == code_male] <- recode_male
182178
# Overwriting temp recode variable
183179
ped$sex <- ped$sex_recode
184180
ped$sex_recode <- NULL
185-
} else if (is.null(code_male) & !is.null(code_female)) {
181+
} else if (is.null(code_male) && !is.null(code_female)) {
186182
# Initialize sex_recode as NA, preserving the length of the 'sex' column
187183
ped$sex_recode <- recode_na
188184
ped$sex_recode[ped$sex != code_female & !is.na(ped$sex)] <- recode_male

0 commit comments

Comments
 (0)