|
a |
|
b/R/plotLong.R |
|
|
1 |
#' Plot Longitudinal Profiles by Cluster |
|
|
2 |
#' |
|
|
3 |
#' This function provides a expression profile representation over time and by cluster. |
|
|
4 |
#' |
|
|
5 |
#' @param object a mixOmics result of class (s)pca, (s)pls, block.(s)pls. |
|
|
6 |
#' @param time (optional) a numeric vector, the same size as \code{ncol(X)}, to change the time scale. |
|
|
7 |
#' @param plot a logical, if TRUE then a plot is produced. Otherwise, the data.frame on which the plot is based on is returned. |
|
|
8 |
#' @param center a logical value indicating whether the variables should be shifted to be zero centered. |
|
|
9 |
#' @param scale a logical value indicating whether the variables should be scaled to have unit variance before the analysis takes place. |
|
|
10 |
#' @param title character indicating the title plot. |
|
|
11 |
#' @param X.label x axis titles. |
|
|
12 |
#' @param Y.label y axis titles. |
|
|
13 |
#' @param legend a logical, to display or not the legend. |
|
|
14 |
#' @param legend.title if \code{legend} is provided, title of the legend. |
|
|
15 |
#' @param legend.block.name a character vector corresponding to the size of the number of blocks in the mixOmics object. |
|
|
16 |
#' |
|
|
17 |
#' |
|
|
18 |
#' @return |
|
|
19 |
#' a data.frame (gathered form) containing the following columns: |
|
|
20 |
#' \item{time}{x axis values} |
|
|
21 |
#' \item{molecule}{names of features} |
|
|
22 |
#' \item{value}{y axis values} |
|
|
23 |
#' \item{cluster}{assigned clusters} |
|
|
24 |
#' \item{block}{name of 'blocks'} |
|
|
25 |
#' |
|
|
26 |
#' @seealso |
|
|
27 |
#' \code{\link[timeOmics]{getCluster}} |
|
|
28 |
#' |
|
|
29 |
#' @examples |
|
|
30 |
#' demo <- suppressWarnings(get_demo_cluster()) |
|
|
31 |
#' X <- demo$X |
|
|
32 |
#' Y <- demo$Y |
|
|
33 |
#' Z <- demo$Z |
|
|
34 |
#' |
|
|
35 |
#' # (s)pca |
|
|
36 |
#' pca.res <- mixOmics::pca(X, ncomp = 3) |
|
|
37 |
#' plotLong(pca.res) |
|
|
38 |
#' spca.res <- mixOmics::spca(X, ncomp =2, keepX = c(15, 10)) |
|
|
39 |
#' plotLong(spca.res) |
|
|
40 |
#' |
|
|
41 |
#' # (s)pls |
|
|
42 |
#' pls.res <- mixOmics::pls(X,Y) |
|
|
43 |
#' plotLong(pls.res) |
|
|
44 |
#' spls.res <- mixOmics::spls(X,Y, keepX = c(15,10), keepY=c(5,6)) |
|
|
45 |
#' plotLong(spls.res) |
|
|
46 |
#' |
|
|
47 |
#' # (s)block.spls |
|
|
48 |
#' block.pls.res <- mixOmics::block.pls(X=list(X=X,Z=Z), Y=Y) |
|
|
49 |
#' plotLong(block.pls.res) |
|
|
50 |
#' block.spls.res <- mixOmics::block.spls(X=list(X=X,Z=Z), Y=Y, |
|
|
51 |
#' keepX = list(X = c(15,10), Z = c(5,6)), |
|
|
52 |
#' keepY = c(3,6)) |
|
|
53 |
#' plotLong(block.spls.res) |
|
|
54 |
#' |
|
|
55 |
#' |
|
|
56 |
#' @import ggplot2 |
|
|
57 |
#' @import mixOmics |
|
|
58 |
#' @importFrom tibble rownames_to_column |
|
|
59 |
#' @importFrom dplyr mutate select left_join |
|
|
60 |
#' @importFrom tidyr pivot_longer |
|
|
61 |
#' @export |
|
|
62 |
plotLong <- function(object, time = NULL, plot = TRUE, center = TRUE, scale = TRUE, |
|
|
63 |
title="Time-course Expression", X.label=NULL, Y.label=NULL, |
|
|
64 |
legend=FALSE, legend.title=NULL, legend.block.name = NULL) |
|
|
65 |
{ |
|
|
66 |
|
|
|
67 |
# Check parameters |
|
|
68 |
#-- object |
|
|
69 |
allowed_object = c("pca", "spca", "mixo_pls", "mixo_spls", "block.pls", "block.spls") |
|
|
70 |
if(!any(class(object) %in% allowed_object)){ |
|
|
71 |
stop("invalid object, should be one of c(pca, spca, mixo_pls, mixo_spls, block.pls, block.spls)") |
|
|
72 |
} |
|
|
73 |
|
|
|
74 |
#-- plot : if plot is not correct, plot = FALSE |
|
|
75 |
if(is.null(plot)) plot = FALSE |
|
|
76 |
if(!is.finite(plot) || !is.logical(plot)){plot = FALSE} |
|
|
77 |
|
|
|
78 |
#-- center |
|
|
79 |
if(is.null(center)) center = TRUE |
|
|
80 |
if(!is.finite(center) || !is.logical(center)){center = TRUE} |
|
|
81 |
|
|
|
82 |
#-- scale |
|
|
83 |
if(is.null(scale)) scale = TRUE |
|
|
84 |
if(!is.finite(scale) || !is.logical(scale)){scale = TRUE} |
|
|
85 |
|
|
|
86 |
# graphical options |
|
|
87 |
#-- title |
|
|
88 |
if(!is.character(title)){title = NULL} |
|
|
89 |
|
|
|
90 |
#-- X.label |
|
|
91 |
if(!is.character(X.label)){X.label = NULL} |
|
|
92 |
|
|
|
93 |
#-- Y.label |
|
|
94 |
if(!is.character(Y.label)){Y.label = NULL} |
|
|
95 |
|
|
|
96 |
#-- legend |
|
|
97 |
if(is.null(legend)) legend = FALSE |
|
|
98 |
if(!is.finite(legend) || !is.logical(legend)){legend = FALSE} |
|
|
99 |
|
|
|
100 |
#-- legend title |
|
|
101 |
if(!is.character(legend.title)){legend.title = NULL} |
|
|
102 |
|
|
|
103 |
# cluster info |
|
|
104 |
cluster <- getCluster(object) |
|
|
105 |
|
|
|
106 |
#-- legend.block.name |
|
|
107 |
if(!is.null(legend.block.name)){ |
|
|
108 |
check_legend.block.name(legend.block.name, cluster) |
|
|
109 |
new.block.name.tmp <- list(new.block = legend.block.name, block = unique(cluster$block)) %>% |
|
|
110 |
as.data.frame |
|
|
111 |
cluster <- cluster %>% left_join(new.block.name.tmp, by = c("block"="block")) %>% |
|
|
112 |
mutate(old.block = block, block = new.block) %>% |
|
|
113 |
dplyr::select(-new.block) |
|
|
114 |
} |
|
|
115 |
|
|
|
116 |
if(is(object, "pca") || is(object, "spca")){ |
|
|
117 |
#-- check time |
|
|
118 |
if(!is.null(time) && (!is_almostInteger_vector(time) || (length(time) != nrow(object$X)))){ |
|
|
119 |
stop("'time' should be a numeric vector") |
|
|
120 |
} |
|
|
121 |
# scale/unscale if desired |
|
|
122 |
data <- unscale(object$X) %>% |
|
|
123 |
as.data.frame() %>% |
|
|
124 |
dplyr::select(intersect(cluster$molecule, colnames(.))) %>% |
|
|
125 |
scale(scale, center) |
|
|
126 |
|
|
|
127 |
|
|
|
128 |
} else if(is(object, "mixo_pls") || is(object, "mixo_spls")){ |
|
|
129 |
#-- check time |
|
|
130 |
if(!is.null(time) && (!is_almostInteger_vector(time) || (length(time) != nrow(object$X)))){ |
|
|
131 |
stop("'time' should be a numeric vector") |
|
|
132 |
} |
|
|
133 |
data.X <- unscale(object$X) %>% |
|
|
134 |
scale(scale, center) |
|
|
135 |
data.Y <- unscale(object$Y) %>% |
|
|
136 |
scale(scale, center) |
|
|
137 |
|
|
|
138 |
data <- cbind(data.X, data.Y) %>% |
|
|
139 |
as.data.frame() %>% |
|
|
140 |
dplyr::select(intersect(cluster$molecule, colnames(.))) |
|
|
141 |
|
|
|
142 |
} else if(is(object, "block.pls") || is(object, "block.spls")){ |
|
|
143 |
#-- check time |
|
|
144 |
if(!is.null(time) &&(!is_almostInteger_vector(time) || (length(time) != nrow(object$X[[1]])))){ |
|
|
145 |
stop("'time' should be a numeric vector") |
|
|
146 |
} |
|
|
147 |
|
|
|
148 |
data <- lapply(object$X, function(i){unscale(i) %>% |
|
|
149 |
scale(scale, center)}) %>% |
|
|
150 |
do.call(what = "cbind") |
|
|
151 |
|
|
|
152 |
data <- as.data.frame(data) %>% |
|
|
153 |
dplyr::select(intersect(cluster$molecule, colnames(.))) |
|
|
154 |
} |
|
|
155 |
|
|
|
156 |
# plot |
|
|
157 |
if(!is.null(time)){ |
|
|
158 |
rownames(data) <- time |
|
|
159 |
} |
|
|
160 |
data.gather <- data %>% |
|
|
161 |
as.data.frame() %>% |
|
|
162 |
tibble::rownames_to_column("time") %>% |
|
|
163 |
dplyr::mutate(time = as.numeric(.$time)) %>% |
|
|
164 |
tidyr::pivot_longer(names_to = "molecule", values_to = "value", -time) %>% |
|
|
165 |
dplyr::left_join(cluster, by = c("molecule"="molecule")) %>% |
|
|
166 |
dplyr::mutate(block = factor(block)) |
|
|
167 |
|
|
|
168 |
gg <- ggplot(data.gather, aes(x = time, y = value, group = molecule)) + |
|
|
169 |
geom_line(aes(color = block)) + |
|
|
170 |
facet_grid(contribution ~ comp, scales = "free") + |
|
|
171 |
scale_color_manual(values = mixOmics::color.mixo(1:length(levels(data.gather$block)))) + |
|
|
172 |
theme_bw() |
|
|
173 |
|
|
|
174 |
if(is.character(title)){ |
|
|
175 |
gg <- gg + ggtitle(title) |
|
|
176 |
} |
|
|
177 |
|
|
|
178 |
if(!is.null(X.label)){ |
|
|
179 |
gg <- gg + xlab(X.label) |
|
|
180 |
} else { |
|
|
181 |
gg <- gg + xlab("Time") |
|
|
182 |
} |
|
|
183 |
|
|
|
184 |
if(!is.null(Y.label)){ |
|
|
185 |
gg <- gg + ylab(Y.label) |
|
|
186 |
} else { |
|
|
187 |
gg <- gg + ylab("Expression") |
|
|
188 |
} |
|
|
189 |
|
|
|
190 |
if(!legend){ |
|
|
191 |
gg <- gg + theme(legend.position = "none") |
|
|
192 |
} else { # legend is TRUE |
|
|
193 |
if(!is.null(legend.title)){ |
|
|
194 |
gg <- gg + labs(color = legend.title) |
|
|
195 |
} |
|
|
196 |
} |
|
|
197 |
|
|
|
198 |
if(plot){ |
|
|
199 |
print(gg) |
|
|
200 |
} |
|
|
201 |
return(invisible(gg$data)) |
|
|
202 |
} |