Skip to content

Commit 3938817

Browse files
authored
Merge pull request #32 from jwfoley/devel
Devel
2 parents 1014f74 + 458128d commit 3938817

File tree

5 files changed

+72
-31
lines changed

5 files changed

+72
-31
lines changed

DESCRIPTION

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
Package: bioanalyzeR
22
Title: Analysis of Agilent electrophoresis data
3-
Version: 0.10.0
3+
Version: 0.10.1
44
Authors@R:
55
person(given = "Joseph",
66
family = "Foley",
77
role = c("aut", "cre"),
8-
email = "[email protected]",
8+
email = "[email protected]",
99
comment = c(ORCID = "0000-0002-1579-5286"))
1010
Description: This package reads raw data and metadata from Agilent automated electrophoresis systems (Bioanalyzer, TapeStation, Fragment Analyzer, ZAG DNA Analyzer, Femto Pulse) into R-friendly data frames. It estimates concentration and molarity for all possible data points. Pre-defined plotting functions use ggplot2 to create attractive graphs of the raw data, as well as the estimated molecule length and molarity, and overlay the peaks and regions of interest reported by the Agilent software. Additional functions streamline common operations like calculating the total concentration or molarity within a region or the molar ratio between two regions.
11-
License: LGPL-3
11+
License: MIT + file LICENSE
1212
Encoding: UTF-8
1313
LazyData: true
14-
Imports: XML, base64enc, png, plyr, ggplot2
14+
Imports: XML, base64enc, plyr, ggplot2
1515
Suggests:
1616
argparse,
1717
knitr,

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Joseph William Foley
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

R/bioanalyzer.R

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,25 @@ read.bioanalyzer <- function(xml.file, method = "hyman", extrapolate = FALSE) {
6363
stringsAsFactors = F
6464
)
6565

66-
# align the observation times according to the markers in this sample
66+
# align the observation times according to the markers in this sample
67+
alignment.coefficient <- NA
68+
alignment.offset <- NA
6769
which.lower.marker <- which(peaks$peak.observations == "Lower Marker" & peaks$concentration == defined.ladder.peaks$Concentration[1]) # check the concentration too because sometimes the software annotates more than one as the same marker with no consequences, and sometimes the size is off by a tiny bit, but the concentration is hardcoded
68-
stopifnot("conflicting lower markers" = length(which.lower.marker) == 1)
69-
if (has.upper.marker) {
70+
if (length(which.lower.marker) > 1) {
71+
warning(paste0("conflicting lower markers in ", batch, " well ", well.number), call. = F)
72+
} else if (length(which.lower.marker) == 0) {
73+
warning(paste0("no lower marker in ", batch, " well ", well.number), call. = F)
74+
} else if (has.upper.marker) { # assay design has lower and upper marker
7075
which.upper.marker <- which(peaks$peak.observations == "Upper Marker" & peaks$concentration == defined.ladder.peaks$Concentration[nrow(defined.ladder.peaks)])
71-
stopifnot("conflicting upper markers" = length(which.upper.marker) == 1)
72-
alignment.coefficient <- diff(peaks$aligned.time[c(which.lower.marker, which.upper.marker)]) / diff(peaks$time[c(which.lower.marker, which.upper.marker)])
73-
alignment.offset <- peaks$aligned.time[which.lower.marker] - alignment.coefficient * peaks$time[which.lower.marker]
74-
} else {
76+
if (length(which.upper.marker) > 1) {
77+
warning(paste0("conflicting upper markers in ", batch, " well ", well.number), call. = F)
78+
} else if (length(which.upper.marker) == 0) {
79+
warning(paste0("no upper marker in ", batch, " well ", well.number), call. = F)
80+
} else {
81+
alignment.coefficient <- diff(peaks$aligned.time[c(which.lower.marker, which.upper.marker)]) / diff(peaks$time[c(which.lower.marker, which.upper.marker)])
82+
alignment.offset <- peaks$aligned.time[which.lower.marker] - alignment.coefficient * peaks$time[which.lower.marker]
83+
}
84+
} else { # assay design has only lower marker not upper
7585
alignment.coefficient <- peaks$aligned.time[which.lower.marker] / peaks$time[which.lower.marker]
7686
alignment.offset <- 0
7787
}
@@ -80,7 +90,7 @@ read.bioanalyzer <- function(xml.file, method = "hyman", extrapolate = FALSE) {
8090
list(
8191
data = raw.data,
8292
samples = data.frame(batch, well.number, sample.name, sample.observations, sample.comment, RIN, is.ladder, stringsAsFactors = F),
83-
peaks = peaks,
93+
peaks = if (nrow(peaks) > 0) peaks else NULL,
8494
alignment.values = c(alignment.coefficient, alignment.offset)
8595
)
8696
}

R/summary.R

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,31 @@
88
#'
99
#' @export
1010
summarize.subset <- function(sample.frame) {
11-
total.molarity <- sum(sample.frame$molarity)
12-
sample.median <- round(sample.frame$length[min(which(cumsum(sample.frame$molarity) >= total.molarity / 2))])
13-
sample.mean <- sum(sample.frame$molarity * sample.frame$length) / total.molarity
14-
length.residuals <- sample.frame$length - sample.mean
15-
sample.sd <- sqrt(sum(sample.frame$molarity * length.residuals^2) / total.molarity)
16-
sample.skewness <- sum(sample.frame$molarity * length.residuals^3) / total.molarity / sample.sd^3
17-
sample.kurtosis <- sum(sample.frame$molarity * length.residuals^4) / total.molarity / sample.sd^4
18-
19-
c(
20-
Median = sample.median,
21-
Mean = sample.mean,
22-
SD = sample.sd,
23-
Skewness = sample.skewness,
24-
Kurtosis = sample.kurtosis
25-
)
11+
if (nrow(sample.frame) < 2) {
12+
c(
13+
Median = NA,
14+
Mean = NA,
15+
SD = NA,
16+
Skewness = NA,
17+
Kurtosis = NA
18+
)
19+
} else {
20+
total.molarity <- sum(sample.frame$molarity)
21+
sample.median <- round(sample.frame$length[min(which(cumsum(sample.frame$molarity) >= total.molarity / 2))])
22+
sample.mean <- sum(sample.frame$molarity * sample.frame$length) / total.molarity
23+
length.residuals <- sample.frame$length - sample.mean
24+
sample.sd <- sqrt(sum(sample.frame$molarity * length.residuals^2) / total.molarity)
25+
sample.skewness <- sum(sample.frame$molarity * length.residuals^3) / total.molarity / sample.sd^3
26+
sample.kurtosis <- sum(sample.frame$molarity * length.residuals^4) / total.molarity / sample.sd^4
27+
28+
c(
29+
Median = sample.median,
30+
Mean = sample.mean,
31+
SD = sample.sd,
32+
Skewness = sample.skewness,
33+
Kurtosis = sample.kurtosis
34+
)
35+
}
2636
}
2737

2838

@@ -73,7 +83,7 @@ summarize.custom <- function(
7383
) {
7484
stopifnot("upper bound must be greater than lower bound" = upper.bound > lower.bound)
7585
in.this.region <- in.custom.region(electrophoresis$data, lower.bound, upper.bound, "length")
76-
result <- as.data.frame(t(simplify2array(by(electrophoresis$data[in.this.region,], electrophoresis$data$sample.index[in.this.region], summarize.subset))))
86+
result <- as.data.frame(t(simplify2array(lapply(unique(electrophoresis$data$sample.index), function(index) summarize.subset(subset(electrophoresis$data, in.this.region & sample.index == index))))))
7787

7888
if (lower.bound == -Inf) {
7989
if (upper.bound != Inf) { # bounded only on right

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ Install the required dependencies:
88

99
Install the newest release (includes 22 MB of demo data):
1010

11-
> install.packages("https://github.com/jwfoley/bioanalyzeR/releases/download/v0.10.0/bioanalyzeR_0.10.0.tar.gz", repos = NULL)
11+
> install.packages("https://github.com/jwfoley/bioanalyzeR/releases/download/v0.10.1/bioanalyzeR_0.10.1.tar.gz", repos = NULL)
1212

1313
or, install the newest release without the demo data:
1414

15-
> install.packages("https://github.com/jwfoley/bioanalyzeR/releases/download/v0.10.0/bioanalyzeR_0.10.0-no_data.tar.gz", repos = NULL)
15+
> install.packages("https://github.com/jwfoley/bioanalyzeR/releases/download/v0.10.1/bioanalyzeR_0.10.1-no_data.tar.gz", repos = NULL)
1616

1717

1818
# Documentation
1919

20-
See the vignette [online](https://stanford.edu/~jwfoley/bioanalyzeR.html) or in R:
20+
See the vignette [online](https://jwfoley.com/bioanalyzeR.html) or in R:
2121

2222
> vignette("bioanalyzeR")
2323

0 commit comments

Comments
 (0)