Diff of /R/plotLong.R [000000] .. [d79ff0]

Switch to unified view

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
}