diff --git a/.gitignore b/.gitignore index 1ea7c83..1947072 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ tests/testthat/*.tif *.xml *.ovr *.jpg +*.xlsx *.png *.svg @@ -20,3 +21,5 @@ tests/testthat/*.tif src-x64/ src-i386/ inst/font + +*/temp diff --git a/DESCRIPTION b/DESCRIPTION index 7ab74b3..7022e4b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: Ipaper Type: Package Title: Collection of personal practical R functions -Version: 0.1.6.9000 +Version: 0.1.7 Authors@R: person("Dongdong", "Kong", email = "kongdd.sysu@gmail.com", role = c("aut", "cre")) Description: Awesome functions in R. @@ -27,7 +27,7 @@ Imports: methods, parallel, doParallel, - foreach, + foreach, iterators, plyr, dplyr, clipr, @@ -38,7 +38,6 @@ Suggests: testthat (>= 2.1.0), knitr, rmarkdown, - iterators, sp, grid, gridExtra diff --git a/NAMESPACE b/NAMESPACE index f7773d1..d23e067 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,7 +1,10 @@ # Generated by roxygen2: do not edit by hand +export("%!in%") export("%<>%") export("%>%") +export("%do%") +export("%dopar%") export(GeomBoxplot2) export(InitCluster) export(OS_type) @@ -31,14 +34,13 @@ export(clamp_min) export(code) export(code_ChrVec) export(contain) -export(cut_levels) +export(cut_plevels) export(data.table) export(dcast2) export(dir.show) export(dt_chr2num) export(dt_round) export(edit_r_profile_sys) -export(ensemble_mean) export(facet_tag) export(file_ext) export(file_name) @@ -59,17 +61,25 @@ export(git_commit_amend) export(git_push) export(git_set_remote) export(github) +export(group_apply) +export(group_upperEnvelope) +export(icount) export(ifelse2) +export(install_git) export(install_gitee) +export(install_github) export(is.data.table) export(is_empty) export(is_wsl) +export(iter) export(key_blind) export(killCluster) export(label_tag) export(last) export(listk) export(llply_par) +export(make_date) +export(make_dt) export(map) export(mapvalues) export(mark_outlier) @@ -87,11 +97,13 @@ export(quantile_envelope) export(read_xlsx) export(read_xlsx2list) export(reorder_name) +export(revalue) export(rm_empty) export(runningId) export(set_dim) export(set_dimnames) export(set_font) +export(set_names) export(setwd_clip) export(sf_rect) export(showfig) @@ -112,11 +124,11 @@ export(which.notna) export(which.notnull) export(write_clip2) export(write_fig) -export(write_fig2ps) export(write_list2xlsx) export(write_sp2rgb) import(clipr) import(ggplot2) +import(iterators) import(magrittr) import(openxlsx) import(readxl) @@ -130,6 +142,8 @@ importFrom(dplyr,first) importFrom(dplyr,last) importFrom(dplyr,mutate) importFrom(foreach,"%do%") +importFrom(foreach,"%dopar%") +importFrom(foreach,foreach) importFrom(ggplot2,aes_string) importFrom(ggplot2,geom_text) importFrom(ggplot2,ggplot_build) @@ -153,6 +167,7 @@ importFrom(grid,textGrob) importFrom(jsonlite,fromJSON) importFrom(jsonlite,read_json) importFrom(jsonlite,write_json) +importFrom(lubridate,make_date) importFrom(lubridate,yday) importFrom(lubridate,year) importFrom(lubridate,ymd) @@ -171,6 +186,8 @@ importFrom(plyr,ddply) importFrom(plyr,llply) importFrom(purrr,map) importFrom(purrr,transpose) +importFrom(remotes,install_git) +importFrom(remotes,install_github) importFrom(rstudioapi,getActiveDocumentContext) importFrom(rstudioapi,getSourceEditorContext) importFrom(rstudioapi,modifyRange) diff --git a/NEWS.md b/NEWS.md index 2ab0f93..ecbed21 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ + +# Ipaper 0.1.7 + +- Many functions are reexported in Ipaper, including `iterators`, `foreach`, `lubridate`, + `data.table`, `dplyr`, `remotes`. One Ipaper is enough. +- Addin `select_word` works +- Git functions works, add `git_commit`, `git_commit_amend`, `git_push` + # Ipaper 0.1.4.9000 * Added a `NEWS.md` file to track changes to the package. @@ -5,5 +13,5 @@ # Ipaper 0.1.5.9000 -* `mkTRend_rcpp` is at least 6-fold faster +* `mkTRend_rcpp` is at least 6-fold faster (moved to rtrend) * add `acf.fft` diff --git a/R/Ipaper-package.R b/R/Ipaper-package.R index 2e7c52c..9c49e81 100644 --- a/R/Ipaper-package.R +++ b/R/Ipaper-package.R @@ -2,7 +2,7 @@ #' @name Ipaper #' @aliases Ipaper-package #' @docType package -#' @keywords download paper DOI +#' @keywords paper #' #' @importFrom jsonlite fromJSON read_json #' @importFrom purrr map transpose diff --git a/R/addin.R b/R/addin.R index 612053a..e6f559d 100644 --- a/R/addin.R +++ b/R/addin.R @@ -127,7 +127,7 @@ key_blind <- function(){ options_update(file_rstudio, options_rstudio) } -#' @importFrom foreach %do% +#' @importFrom foreach %do% %dopar% #' @importFrom jsonlite write_json read_json #' @export options_update <- function(file, options.new) { diff --git a/R/cut_levels.R b/R/cut_levels.R deleted file mode 100644 index 3cea414..0000000 --- a/R/cut_levels.R +++ /dev/null @@ -1,50 +0,0 @@ -#' cut_levels -#' -#' @param x numeric vector -#' @param pvalue p <= `x%`, means its significant at `x%` level -#' -#' @examples -#' x <- c(-0.09, -0.4, 0.04, 0.15) -#' cut_levels(x, verbose = TRUE) -#' @export -cut_levels <- function(x, pvalue = c(0.01, 0.05, 0.1), verbose = FALSE){ - np <- length(pvalue) + 1 - pvalue2 <- pvalue %>% c(., 1) %>% c(-rev(.), 0, .) - - levels_num <- cut(1, pvalue2) %>% levels() %>% { - c(rev(.[1:np]), rev(.[-(1:np)])) %>% rev() - } - levels_str <- c( - sprintf("significant increasing at the %-4s level", as.character(pvalue)), - "insignificant increasing", - "insignificant decreasing", - sprintf("significant decreasing at the %-4s level", rev(as.character(pvalue)))) - levels <- cbind(levels_num, levels_str) - if (verbose) print(levels) - - xf <- cut(x, pvalue2) %>% factor(levels_num, levels_str) - xf -} - -#' @export -mapvalues <- function (x, from, to, warn_missing = TRUE) { - if (length(from) != length(to)) { - stop("`from` and `to` vectors are not the same length.") - } - if (!is.atomic(x)) { - stop("`x` must be an atomic vector.") - } - if (is.factor(x)) { - levels(x) <- mapvalues(levels(x), from, to, warn_missing) - return(x) - } - mapidx <- match(x, from) - mapidxNA <- is.na(mapidx) - from_found <- sort(unique(mapidx)) - if (warn_missing && length(from_found) != length(from)) { - message("The following `from` values were not present in `x`: ", - paste(from[!(1:length(from) %in% from_found)], collapse = ", ")) - } - x[!mapidxNA] <- to[mapidx[!mapidxNA]] - x -} diff --git a/R/dcast2.R b/R/dcast2.R deleted file mode 100644 index 816b78a..0000000 --- a/R/dcast2.R +++ /dev/null @@ -1,7 +0,0 @@ -#' @export -dcast2 <- function(d, by, value.var = "value", ...){ - vars_left <- setdiff(colnames(d), c(by, value.var)) %>% paste(collapse = "+") - vars_right <- by %>% paste(collapse = "+") - formula <- as.formula(sprintf("%s~%s", vars_left, vars_right)) - dcast(d, formula, value.var = value.var, ...) -} diff --git a/R/dplyr.R b/R/dplyr.R index 62fa44b..d7cad2c 100644 --- a/R/dplyr.R +++ b/R/dplyr.R @@ -1,6 +1,3 @@ -#' @export -transpose <- purrr::transpose - #' @title data.frame manipulating function by `dplyr::across` #' @name dt_tools NULL @@ -20,3 +17,22 @@ dt_chr2num <- function(d) { } # https://stackoverflow.com/questions/54774280/plyrddply-equivalent-in-dplyr + +#' @export +dcast2 <- function(d, by, value.var = "value", ...) { + vars_left <- setdiff(colnames(d), c(by, value.var)) %>% paste(collapse = "+") + vars_right <- by %>% paste(collapse = "+") + formula <- as.formula(sprintf("%s~%s", vars_left, vars_right)) + dcast(d, formula, value.var = value.var, ...) +} + +#' @export +make_dt <- function(..., ncol = 3) { + x <- list(...) + n <- length(x) + nrow <- floor(n / ncol) + lapply(1:nrow, function(i) { + ind <- seq((i - 1) * ncol + 1, i * ncol) + x[ind] %>% as.data.table() + }) %>% do.call(rbind, .) +} diff --git a/R/set_names_foreach.R b/R/foreach.R similarity index 100% rename from R/set_names_foreach.R rename to R/foreach.R diff --git a/R/git.R b/R/git.R index d577855..0db298a 100644 --- a/R/git.R +++ b/R/git.R @@ -38,6 +38,25 @@ github <- function(path = getwd()) { system(cmd) } +# #' @rdname install_gitee +# #' @export +# install <- install_local + +# #' @importFrom devtools document load_all +# #' @export +# load_all2 <- function(path = ".", ...){ +# document(path, ...) +# load_all(path, ...) +# } + +#' @importFrom remotes install_github +#' @export +remotes::install_github + +#' @importFrom remotes install_git +#' @export +remotes::install_git + #' Attempts to install a package directly from gitee. #' #' @param Repository address in the format `username/repo[/subdir][@ref|#pull]`. @@ -55,19 +74,3 @@ install_gitee <- function(repo) { install_git(url) } } - -# #' @rdname install_gitee -# #' @export -# install <- install_local - -# #' @rdname install_gitee -# #' @importFrom remotes install_git install_github -# #' @export -# install_github <- install_github - -# #' @importFrom devtools document load_all -# #' @export -# load_all2 <- function(path = ".", ...){ -# document(path, ...) -# load_all(path, ...) -# } diff --git a/R/upper_envelope.R b/R/group_apply.R similarity index 66% rename from R/upper_envelope.R rename to R/group_apply.R index ea51511..a6d9f09 100644 --- a/R/upper_envelope.R +++ b/R/group_apply.R @@ -1,33 +1,11 @@ -#' function to separate data to steps of x, obtain 95 quantile value for smooth -#' @export -upper_envelope <- function(x, y, step = 0.2, alpha = 0.95){ - xrange <- range(x, na.rm = T) - - brks <- seq(xrange[1], xrange[2], by = step) - n <- length(brks) - xmid <- (brks[-n] + brks[-1])/2 - - brks[n] <- Inf - - res <- numeric(n-1)*NA_real_ - - for (i in 1:(n-1)){ - val_min <- brks[i] - val_max <- brks[i+1] - - I <- x >= val_min & x < val_max - res[i] <- quantile(y[I], alpha, na.rm = T) - } - - data.table(x = xmid, y = res) -} - -#' ensemble_mean +#' group_apply #' +#' @param chunk split data into nchunks, and apply `FUN` in every group #' @param FUN function of mean or median +#' @param ... others to `FUN` #' #' @export -ensemble_mean <- function(x, y, step = 0.2, chunk=NULL, FUN = "mean") { +group_apply <- function(x, y, step = 0.2, chunk=NULL, FUN = "mean", ...) { FUN <- get(FUN, mode="function") xrange <- range(x, na.rm = T) @@ -60,3 +38,33 @@ ensemble_mean <- function(x, y, step = 0.2, chunk=NULL, FUN = "mean") { } data.table(x = xmid, y = res) } + +#' function to separate data to steps of x, obtain 95 quantile value for smooth +#' +#' @rdname group_apply +#' @export +group_upperEnvelope <- function(x, y, step = 0.2, alpha = 0.95) { + xrange <- range(x, na.rm = T) + + brks <- seq(xrange[1], xrange[2], by = step) + n <- length(brks) + xmid <- (brks[-n] + brks[-1]) / 2 + + brks[n] <- Inf + + res <- numeric(n - 1) * NA_real_ + + for (i in 1:(n - 1)) { + val_min <- brks[i] + val_max <- brks[i + 1] + + I <- x >= val_min & x < val_max + res[i] <- quantile(y[I], alpha, na.rm = T) + } + + data.table(x = xmid, y = res) +} + +#' @keywords internal +#' @export +upper_envelope <- group_upperEnvelope diff --git a/R/path_func.R b/R/path_func.R index 6efe025..9dc4750 100644 --- a/R/path_func.R +++ b/R/path_func.R @@ -32,8 +32,8 @@ check_path <- function(path) { path } -#' edit R profile by sublime -#' +#' edit R profile by VScode +#' @keywords internal #' @export edit_r_profile_sys <- function(){ code(file.path(R.home(), "etc")) # /Rprofile.site diff --git a/R/reexports.R b/R/reexports.R new file mode 100644 index 0000000..51acda6 --- /dev/null +++ b/R/reexports.R @@ -0,0 +1,55 @@ +#' @export +transpose <- purrr::transpose + +#' @importFrom dplyr first last mutate +#' @export +dplyr::first + +#' @export +dplyr::last + +#' @export +dplyr::mutate + +#' @export +magrittr::`%>%` + +#' @export +magrittr::`%<>%` + +#' @export +magrittr::set_names + +#' @export +purrr::map + +#' @importFrom data.table data.table is.data.table as.data.table +#' @export +data.table::data.table + +#' @export +data.table::is.data.table + +#' @export +data.table::as.data.table + +#' @importFrom lubridate make_date +#' @export +lubridate::make_date + +#' @importFrom foreach foreach %do% %dopar% +#' @export +foreach::`%dopar%` + +#' @export +foreach::`%do%` + +#' @import iterators +#' @export +iterators::iter + +#' @export +iterators::icount + +# #' @export +# lubridate::date diff --git a/R/revalue.R b/R/revalue.R new file mode 100644 index 0000000..61c41fa --- /dev/null +++ b/R/revalue.R @@ -0,0 +1,93 @@ +#' Replace specified values with new values, in a factor or character vector. +#' +#' If \code{x} is a factor, the named levels of the factor will be +#' replaced with the new values. +#' +#' This function works only on character vectors and factors, but the +#' related \code{mapvalues} function works on vectors of any type and factors, +#' and instead of a named vector specifying the original and replacement values, +#' it takes two separate vectors +#' +#' @param x factor or character vector to modify +#' @param replace named character vector, with new values as values, and +#' old values as names. +#' @param warn_missing print a message if any of the old values are +#' not actually present in \code{x} +#' +#' @seealso \code{\link{mapvalues}} to replace values with vectors of any type +#' @export +#' @examples +#' x <- c("a", "b", "c") +#' revalue(x, c(a = "A", c = "C")) +#' revalue(x, c("a" = "A", "c" = "C")) +#' +#' y <- factor(c("a", "b", "c", "a")) +#' revalue(y, c(a = "A", c = "C")) +revalue <- function(x, replace = NULL, warn_missing = TRUE) { + if (!is.null(x) && !is.factor(x) && !is.character(x)) { + stop("x is not a factor or a character vector.") + } + mapvalues(x, from = names(replace), to = replace, warn_missing = warn_missing) +} + + +#' Replace specified values with new values, in a vector or factor. +#' +#' Item in \code{x} that match items \code{from} will be replaced by +#' items in \code{to}, matched by position. For example, items in \code{x} that +#' match the first element in \code{from} will be replaced by the first +#' element of \code{to}. +#' +#' If \code{x} is a factor, the matching levels of the factor will be +#' replaced with the new values. +#' +#' The related \code{revalue} function works only on character vectors +#' and factors, but this function works on vectors of any type and factors. +#' +#' @param x the factor or vector to modify +#' @param from a vector of the items to replace +#' @param to a vector of replacement values +#' @param warn_missing print a message if any of the old values are +#' not actually present in \code{x} +#' +#' @seealso \code{\link{revalue}} to do the same thing but with a single +#' named vector instead of two separate vectors. +#' @export +#' @examples +#' x <- c("a", "b", "c") +#' mapvalues(x, c("a", "c"), c("A", "C")) +#' +#' # Works on factors +#' y <- factor(c("a", "b", "c", "a")) +#' mapvalues(y, c("a", "c"), c("A", "C")) +#' +#' # Works on numeric vectors +#' z <- c(1, 4, 5, 9) +#' mapvalues(z, from = c(1, 5, 9), to = c(10, 50, 90)) +mapvalues <- function(x, from, to, warn_missing = TRUE) { + if (length(from) != length(to)) { + stop("`from` and `to` vectors are not the same length.") + } + if (!is.atomic(x)) { + stop("`x` must be an atomic vector.") + } + + if (is.factor(x)) { + # If x is a factor, call self but operate on the levels + levels(x) <- mapvalues(levels(x), from, to, warn_missing) + return(x) + } + + mapidx <- match(x, from) + mapidxNA <- is.na(mapidx) + + # index of items in `from` that were found in `x` + from_found <- sort(unique(mapidx)) + if (warn_missing && length(from_found) != length(from)) { + message("The following `from` values were not present in `x`: ", + paste(from[!(1:length(from) %in% from_found) ], collapse = ", ")) + } + + x[!mapidxNA] <- to[mapidx[!mapidxNA]] + x +} diff --git a/R/tools.R b/R/tools.R index c5492eb..ebc7388 100644 --- a/R/tools.R +++ b/R/tools.R @@ -39,30 +39,6 @@ tabular <- function(df, ...) { contents, "\n}\n", sep = "") } -#' obj.size -#' -#' Get object size in `unit` -#' @param obj Object -#' @param unit "Kb", "Mb" or "Gb" -#' -#' @examples -#' obj.size(1:100) -#' @export -obj.size <- function(obj, unit = "Mb") { - cat(format(object.size(obj), unit), "\n") -} - -#' file_size -#' -#' @param file file path -#' @export -file_size <- function(file) { - utils:::format.object_size(file.size(file), "auto") -} - -#' @export -str_year <- function(x) stringr::str_extract(basename(x), "\\d{4}") - #' ifelse2 #' #' ternary operator just like java `test ? yes : no` @@ -106,38 +82,35 @@ match2 <- function(x, y) { d } +#' cut_plevels +#' +#' @param x numeric vector +#' @param pvalue p <= `x%`, means its significant at `x%` level +#' +#' @examples +#' x <- c(-0.09, -0.4, 0.04, 0.15) +#' cut_plevels(x, verbose = TRUE) +#' @export +cut_plevels <- function(x, pvalue = c(0.01, 0.05, 0.1), verbose = FALSE) { + np <- length(pvalue) + 1 + pvalue2 <- pvalue %>% + c(., 1) %>% + c(-rev(.), 0, .) + + levels_num <- cut(1, pvalue2) %>% + levels() %>% + { + c(rev(.[1:np]), rev(.[-(1:np)])) %>% rev() + } + levels_str <- c( + sprintf("significant increasing at the %-4s level", as.character(pvalue)), + "insignificant increasing", + "insignificant decreasing", + sprintf("significant decreasing at the %-4s level", rev(as.character(pvalue))) + ) + levels <- cbind(levels_num, levels_str) + if (verbose) print(levels) -#' @importFrom dplyr first last mutate -#' @export -dplyr::first - -#' @export -dplyr::last - -#' @export -dplyr::mutate - -#' @export -magrittr::`%>%` - -#' @export -magrittr::`%<>%` - -#' @export -purrr::map - -#' @importFrom data.table data.table is.data.table as.data.table -#' @export -data.table::data.table - -#' @export -data.table::is.data.table - -#' @export -data.table::as.data.table - -# #' @export -# lubridate::yday - -# #' @export -# lubridate::date + xf <- cut(x, pvalue2) %>% factor(levels_num, levels_str) + xf +} diff --git a/R/url_filezilla.R b/R/tools_external_apps.R similarity index 100% rename from R/url_filezilla.R rename to R/tools_external_apps.R diff --git a/R/file_name.R b/R/tools_file.R similarity index 73% rename from R/file_name.R rename to R/tools_file.R index 0dc0f9b..7319ecc 100644 --- a/R/file_name.R +++ b/R/tools_file.R @@ -13,6 +13,9 @@ str_locate_all <- function(x, pattern) { data.table(I = seq_along(ans), start = ans, end = attr(ans, "match.length") + ans - 1) } +#' @export +str_year <- function(x) str_extract(basename(x), "\\d{4}") + #' @export #' @rdname file_name file_ext <- function(file) { @@ -49,3 +52,24 @@ file_name <- function(file) { # *: zero or more # +: one or more } + +#' obj.size +#' +#' Get object size in `unit` +#' @param obj Object +#' @param unit "Kb", "Mb" or "Gb" +#' +#' @examples +#' obj.size(1:100) +#' @export +obj.size <- function(obj, unit = "Mb") { + cat(format(object.size(obj), unit), "\n") +} + +#' file_size +#' +#' @param file file path +#' @export +file_size <- function(file) { + utils:::format.object_size(file.size(file), "auto") +} diff --git a/R/tools_plot.R b/R/tools_plot.R index 1aa8aec..546ea6d 100644 --- a/R/tools_plot.R +++ b/R/tools_plot.R @@ -7,13 +7,3 @@ add_gridLine <- function(dates, col = "grey60", lty = 3, ...) { t_grids <- seq.Date(date_beg, date_end, by = "year") abline(v = t_grids, col = col, lty = lty, ...) } - -make_dt <- function(..., ncol = 3) { - x <- list(...) - n <- length(x) - nrow <- floor(n / ncol) - lapply(1:nrow, function(i) { - ind <- seq((i - 1) * ncol + 1, i * ncol) - x[ind] %>% as.data.table() - }) %>% do.call(rbind, .) -} diff --git a/R/tools_sp.R b/R/tools_sp.R index 8f63924..2ee7c05 100644 --- a/R/tools_sp.R +++ b/R/tools_sp.R @@ -30,7 +30,6 @@ sf_rect <- function(range, crs = st_crs(4326)){ #' @param mask Boolean vector indicate where to mask #' @param col_mask #' -#' #' @examples #' \dontrun{ #' write_sp2rgb(grid, brks, cols, file = "dem_pearl_rgb.tif") diff --git a/R/which.R b/R/which.R index e71b5ed..6ab03d5 100644 --- a/R/which.R +++ b/R/which.R @@ -22,3 +22,8 @@ which.isnull <- function(x) { which.notnull <- function(x) { which(!sapply(x, is.null)) } + +#' @export +`%!in%` <- function(x, table) { + !(x %in% table) +} diff --git a/R/write_fig2ps.R b/R/write_fig2ps.R deleted file mode 100644 index b7605a0..0000000 --- a/R/write_fig2ps.R +++ /dev/null @@ -1,79 +0,0 @@ -#' write_fig2ps -#' -#' Write figure to pages -#' Subplots xlab and ylab are unified, and only keet singe one. -#' Currently, only support ggplot figures; And only support arrange figures -#' into rows (nrow*1). -#' -#' @param ps A list of ggplot figure objects. And -#' @param lgd A grid grob object, legend to show in the bottom. -#' @param ylab.right y label title -#' @param width inch -#' @param height inch -#' @param nrow -#' -#' @export -write_fig2ps <- function(ps, lgd, ylab.right, file, width = 10, height, nrow = 6){ - npage <- ceiling(length(ps)/nrow) - if (missing(height)) height = nrow*1.6 - - ylab.left <- ps[[1]]$labels$y - ylab.left.color <- ps[[1]]$theme$axis.title.y.left$colour - ylab.right.color <- ps[[1]]$theme$axis.title.y.right$colour - - params <- list(ncol = 1, padding = unit(1, "line"), - left = textGrob(ylab.left , rot = 90, - gp=gpar(fontsize=14, col=ylab.left.color)) ) - - # parameters for arrangeGrob - if (!missing(ylab.right)) - params$right = textGrob(ylab.right, rot = 270, - gp=gpar(fontsize=14, col=ylab.right.color)) - - Cairo::CairoPDF(file, width, height) - for (i in 1:npage){ - runningId(i) - I_beg <- (i - 1) * nrow + 1 - I_end <- min(i*nrow, length(ps)) - - I <- I_beg:I_end - n <- length(I) - - ps_i <- ps[I] - for (j in seq_along(I)){ - theme_j <- theme( - axis.text.x = element_blank(), - axis.title = element_blank(), - axis.title.y.right = element_blank(), - axis.title.y.left = element_blank(), - legend.position="none" - ) - if (j == n) - theme_j <- theme( - axis.title.y.right = element_blank(), - axis.title.y.left = element_blank(), - legend.position="none" ) - ps_i[[j]] <- ps_i[[j]] + theme_j - } - - ps_i <- c(ps_i, list(lgd)) - nx <- length(ps_i) - - params$grobs <- ps_i - params$nrow <- nx - - if (missing(lgd)){ - params$heights <- c(rep(5, nx - 1), 5.5) - } else{ - params$heights <- c(rep(5, nx - 2), 5.5, 2) - } - - g <- do.call(gridExtra::arrangeGrob, params) - - if (i != 1) grid.newpage(); - grid::grid.draw(g) - } - dev.off() - file.show(file) -} - diff --git a/man/Ipaper.Rd b/man/Ipaper.Rd index 340ce08..6343b07 100644 --- a/man/Ipaper.Rd +++ b/man/Ipaper.Rd @@ -13,7 +13,5 @@ Awesome functions in R. \strong{Maintainer}: Dongdong Kong \email{kongdd.sysu@gmail.com} } -\keyword{DOI} -\keyword{download} \keyword{internal} \keyword{paper} diff --git a/man/cut_levels.Rd b/man/cut_plevels.Rd similarity index 52% rename from man/cut_levels.Rd rename to man/cut_plevels.Rd index bd1ff78..3140eeb 100644 --- a/man/cut_levels.Rd +++ b/man/cut_plevels.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/cut_levels.R -\name{cut_levels} -\alias{cut_levels} -\title{cut_levels} +% Please edit documentation in R/tools.R +\name{cut_plevels} +\alias{cut_plevels} +\title{cut_plevels} \usage{ -cut_levels(x, pvalue = c(0.01, 0.05, 0.1), verbose = FALSE) +cut_plevels(x, pvalue = c(0.01, 0.05, 0.1), verbose = FALSE) } \arguments{ \item{x}{numeric vector} @@ -12,9 +12,9 @@ cut_levels(x, pvalue = c(0.01, 0.05, 0.1), verbose = FALSE) \item{pvalue}{p <= \verb{x\%}, means its significant at \verb{x\%} level} } \description{ -cut_levels +cut_plevels } \examples{ x <- c(-0.09, -0.4, 0.04, 0.15) -cut_levels(x, verbose = TRUE) +cut_plevels(x, verbose = TRUE) } diff --git a/man/edit_r_profile_sys.Rd b/man/edit_r_profile_sys.Rd index b1b73b7..75b126b 100644 --- a/man/edit_r_profile_sys.Rd +++ b/man/edit_r_profile_sys.Rd @@ -2,10 +2,11 @@ % Please edit documentation in R/path_func.R \name{edit_r_profile_sys} \alias{edit_r_profile_sys} -\title{edit R profile by sublime} +\title{edit R profile by VScode} \usage{ edit_r_profile_sys() } \description{ -edit R profile by sublime +edit R profile by VScode } +\keyword{internal} diff --git a/man/ensemble_mean.Rd b/man/ensemble_mean.Rd deleted file mode 100644 index 78ec836..0000000 --- a/man/ensemble_mean.Rd +++ /dev/null @@ -1,14 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/upper_envelope.R -\name{ensemble_mean} -\alias{ensemble_mean} -\title{ensemble_mean} -\usage{ -ensemble_mean(x, y, step = 0.2, chunk = NULL, FUN = "mean") -} -\arguments{ -\item{FUN}{function of mean or median} -} -\description{ -ensemble_mean -} diff --git "a/man/examples/\346\265\213\350\257\225\345\255\227\344\275\223.R" b/man/examples/test-font.R similarity index 100% rename from "man/examples/\346\265\213\350\257\225\345\255\227\344\275\223.R" rename to man/examples/test-font.R diff --git a/man/file_name.Rd b/man/file_name.Rd index 9e73575..6b4c00c 100644 --- a/man/file_name.Rd +++ b/man/file_name.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/file_name.R +% Please edit documentation in R/tools_file.R \name{file_ext} \alias{file_ext} \alias{file_name} diff --git a/man/file_size.Rd b/man/file_size.Rd index d037906..e2ac9d6 100644 --- a/man/file_size.Rd +++ b/man/file_size.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/tools_file.R \name{file_size} \alias{file_size} \title{file_size} diff --git a/man/group_apply.Rd b/man/group_apply.Rd new file mode 100644 index 0000000..93475a1 --- /dev/null +++ b/man/group_apply.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/group_apply.R +\name{group_apply} +\alias{group_apply} +\alias{group_upperEnvelope} +\title{group_apply} +\usage{ +group_apply(x, y, step = 0.2, chunk = NULL, FUN = "mean", ...) + +group_upperEnvelope(x, y, step = 0.2, alpha = 0.95) +} +\arguments{ +\item{chunk}{split data into nchunks, and apply \code{FUN} in every group} + +\item{FUN}{function of mean or median} + +\item{...}{others to \code{FUN}} +} +\description{ +group_apply + +function to separate data to steps of x, obtain 95 quantile value for smooth +} diff --git a/man/mapvalues.Rd b/man/mapvalues.Rd new file mode 100644 index 0000000..7f2f2bd --- /dev/null +++ b/man/mapvalues.Rd @@ -0,0 +1,47 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/revalue.R +\name{mapvalues} +\alias{mapvalues} +\title{Replace specified values with new values, in a vector or factor.} +\usage{ +mapvalues(x, from, to, warn_missing = TRUE) +} +\arguments{ +\item{x}{the factor or vector to modify} + +\item{from}{a vector of the items to replace} + +\item{to}{a vector of replacement values} + +\item{warn_missing}{print a message if any of the old values are +not actually present in \code{x}} +} +\description{ +Item in \code{x} that match items \code{from} will be replaced by +items in \code{to}, matched by position. For example, items in \code{x} that +match the first element in \code{from} will be replaced by the first +element of \code{to}. +} +\details{ +If \code{x} is a factor, the matching levels of the factor will be +replaced with the new values. + +The related \code{revalue} function works only on character vectors +and factors, but this function works on vectors of any type and factors. +} +\examples{ +x <- c("a", "b", "c") +mapvalues(x, c("a", "c"), c("A", "C")) + +# Works on factors +y <- factor(c("a", "b", "c", "a")) +mapvalues(y, c("a", "c"), c("A", "C")) + +# Works on numeric vectors +z <- c(1, 4, 5, 9) +mapvalues(z, from = c(1, 5, 9), to = c(10, 50, 90)) +} +\seealso{ +\code{\link{revalue}} to do the same thing but with a single +named vector instead of two separate vectors. +} diff --git a/man/obj.size.Rd b/man/obj.size.Rd index 27cebd1..ee23978 100644 --- a/man/obj.size.Rd +++ b/man/obj.size.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/tools_file.R \name{obj.size} \alias{obj.size} \title{obj.size} diff --git a/man/reexports.Rd b/man/reexports.Rd index d7cdffe..a17a78f 100644 --- a/man/reexports.Rd +++ b/man/reexports.Rd @@ -1,17 +1,25 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/git.R, R/reexports.R \docType{import} \name{reexports} \alias{reexports} +\alias{install_github} +\alias{install_git} \alias{first} \alias{last} \alias{mutate} \alias{\%>\%} \alias{\%<>\%} +\alias{set_names} \alias{map} \alias{data.table} \alias{is.data.table} \alias{as.data.table} +\alias{make_date} +\alias{\%dopar\%} +\alias{\%do\%} +\alias{iter} +\alias{icount} \title{Objects exported from other packages} \keyword{internal} \description{ @@ -23,8 +31,16 @@ below to see their documentation. \item{dplyr}{\code{\link[dplyr:nth]{first}}, \code{\link[dplyr:nth]{last}}, \code{\link[dplyr]{mutate}}} - \item{magrittr}{\code{\link[magrittr:compound]{\%<>\%}}, \code{\link[magrittr:pipe]{\%>\%}}} + \item{foreach}{\code{\link[foreach:foreach]{\%do\%}}, \code{\link[foreach:foreach]{\%dopar\%}}} + + \item{iterators}{\code{\link[iterators]{icount}}, \code{\link[iterators]{iter}}} + + \item{lubridate}{\code{\link[lubridate:make_datetime]{make_date}}} + + \item{magrittr}{\code{\link[magrittr:compound]{\%<>\%}}, \code{\link[magrittr:pipe]{\%>\%}}, \code{\link[magrittr:aliases]{set_names}}} \item{purrr}{\code{\link[purrr]{map}}} + + \item{remotes}{\code{\link[remotes]{install_git}}, \code{\link[remotes]{install_github}}} }} diff --git a/man/revalue.Rd b/man/revalue.Rd new file mode 100644 index 0000000..c3c1f28 --- /dev/null +++ b/man/revalue.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/revalue.R +\name{revalue} +\alias{revalue} +\title{Replace specified values with new values, in a factor or character vector.} +\usage{ +revalue(x, replace = NULL, warn_missing = TRUE) +} +\arguments{ +\item{x}{factor or character vector to modify} + +\item{replace}{named character vector, with new values as values, and +old values as names.} + +\item{warn_missing}{print a message if any of the old values are +not actually present in \code{x}} +} +\description{ +If \code{x} is a factor, the named levels of the factor will be +replaced with the new values. +} +\details{ +This function works only on character vectors and factors, but the +related \code{mapvalues} function works on vectors of any type and factors, +and instead of a named vector specifying the original and replacement values, +it takes two separate vectors +} +\examples{ +x <- c("a", "b", "c") +revalue(x, c(a = "A", c = "C")) +revalue(x, c("a" = "A", "c" = "C")) + +y <- factor(c("a", "b", "c", "a")) +revalue(y, c(a = "A", c = "C")) +} +\seealso{ +\code{\link{mapvalues}} to replace values with vectors of any type +} diff --git a/man/upper_envelope.Rd b/man/upper_envelope.Rd deleted file mode 100644 index 2c1a930..0000000 --- a/man/upper_envelope.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/upper_envelope.R -\name{upper_envelope} -\alias{upper_envelope} -\title{function to separate data to steps of x, obtain 95 quantile value for smooth} -\usage{ -upper_envelope(x, y, step = 0.2, alpha = 0.95) -} -\description{ -function to separate data to steps of x, obtain 95 quantile value for smooth -} diff --git a/man/write_fig2ps.Rd b/man/write_fig2ps.Rd deleted file mode 100644 index 11cf67a..0000000 --- a/man/write_fig2ps.Rd +++ /dev/null @@ -1,27 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/write_fig2ps.R -\name{write_fig2ps} -\alias{write_fig2ps} -\title{write_fig2ps} -\usage{ -write_fig2ps(ps, lgd, ylab.right, file, width = 10, height, nrow = 6) -} -\arguments{ -\item{ps}{A list of ggplot figure objects. And} - -\item{lgd}{A grid grob object, legend to show in the bottom.} - -\item{ylab.right}{y label title} - -\item{width}{inch} - -\item{height}{inch} - -\item{nrow}{} -} -\description{ -Write figure to pages -Subplots xlab and ylab are unified, and only keet singe one. -Currently, only support ggplot figures; And only support arrange figures -into rows (nrow*1). -} diff --git a/tests/testthat/test-clamp.R b/tests/testthat/test-clamp.R new file mode 100644 index 0000000..077afba --- /dev/null +++ b/tests/testthat/test-clamp.R @@ -0,0 +1,12 @@ +test_that("clamp works", { + x = 1:10 + + r = clamp(x, c(2, 8)) + expect_equal(min(r), 2) + expect_equal(max(r), 8) + + # + r = clamp(x, c(2, 8), fill.na = TRUE) + expect_equal(which.notna(r), 2:8) + expect_equal(which.na(r), c(1, 9, 10)) +}) diff --git a/tests/testthat/test-group_apply.R b/tests/testthat/test-group_apply.R new file mode 100644 index 0000000..0573575 --- /dev/null +++ b/tests/testthat/test-group_apply.R @@ -0,0 +1,17 @@ +test_that("upper_envelope works", { + y = rnorm(1000) + x = seq_along(y) + + + expect_true({ + r = group_upperEnvelope(x, y, 20) + plot(x, y) + lines(y~x, r, col = "red") + is.data.table(r) && nrow(r) == 49 + }) + + expect_true({ + r2 = group_apply(x, y, chunk = 20) + is.data.table(r2) && nrow(r2) == 49 + }) +}) diff --git a/tests/testthat/test-listk.R b/tests/testthat/test-listk.R index f8370bf..31d1909 100644 --- a/tests/testthat/test-listk.R +++ b/tests/testthat/test-listk.R @@ -1,4 +1,4 @@ -test_that("multiplication works", { +test_that("listk works", { a = 1 b = 1:2 c = 1:3 diff --git a/tests/testthat/test-revalue.R b/tests/testthat/test-revalue.R new file mode 100644 index 0000000..12aecb1 --- /dev/null +++ b/tests/testthat/test-revalue.R @@ -0,0 +1,137 @@ +context("Replace values") + + +# Character vector +chr <- c("A2", "A1", "A3", "A1") +# Factor: To complicate things, set levels in a different order +fac <- factor(c("A1", "A2", "A3"), levels=c("A2", "A1", "A3")) +# Numeric vector +num <- c(4, 1, 5, 8) + + +# test warn if any missing + +test_that("Empty mapping results in no change", { + expect_identical(mapvalues(chr, from = NULL, to = NULL), chr) + expect_identical(revalue(chr, NULL), chr) + + expect_identical(mapvalues(fac, from = NULL, to = NULL), fac) + expect_identical(revalue(fac, NULL), fac) +}) + +test_that("Basic mapping works", { + newchr <- c("B2", "A1", "B3", "A1") + expect_identical(mapvalues(chr, c("A3", "A2"), c("B3", "B2")), newchr) + expect_identical(revalue(chr, c(A3="B3", A2="B2")), newchr) + + newfac <- factor(c("A1", "B2", "B3"), levels=c("B2", "A1", "B3")) + expect_identical(mapvalues(fac, c("A3", "A2"), c("B3", "B2")), newfac) + expect_identical(revalue(fac, c(A3="B3", A2="B2")), newfac) + + newnum <- c(40, 1, 5, 80) + expect_identical(mapvalues(num, c(4, 8), c(40, 80)), newnum) + # revalue doesn't work for numeric vectors +}) + +test_that("Mapping with repeated original values - uses first instance, and gives message", { + newchr <- c("A2", "B1", "A3", "B1") + expect_message( + expect_identical(mapvalues(chr, c("A1", "A1"), c("B1", "C1")), newchr)) + expect_message( + expect_identical(revalue(chr, c(A1="B1", A1="C1")), newchr)) + + + newfac <- factor(c("B1", "A2", "A3"), levels=c("A2", "B1", "A3")) + expect_message( + expect_identical(mapvalues(fac, c("A1", "A1"), c("B1", "C1")), newfac)) + expect_message( + expect_identical(revalue(fac, c(A1="B1", A1="C1")), newfac)) + + newnum <- c(4, 1, 5, 80) + expect_message( + expect_identical(mapvalues(num, c(8, 8), c(80, 800)), newnum)) +}) + +test_that("Mapping with repeated new value (for factors, levels are in earliest position)", { + newchr <- c("BX", "A1", "BX", "A1") + expect_identical(mapvalues(chr, c("A3", "A2"), c("BX", "BX")), newchr) + expect_identical(revalue(chr, c(A3="BX", A2="BX")), newchr) + + + newfac <- factor(c("A1", "BX", "BX"), levels=c("BX", "A1")) + expect_identical(revalue(fac, c(A3="BX", A2="BX")), newfac) + + # Factors can have levels in different orders + newfac2 <- factor(c("BX", "A2", "BX"), levels=c("A2", "BX")) + expect_identical(revalue(fac, c(A3="BX", A1="BX")), newfac2) +}) + +test_that("Mapping with multiple matches works", { + newchr <- c("B2", "B1", "A3", "B1") + expect_identical(mapvalues(chr, c("A1", "A2"), c("B1", "B2")), newchr) + expect_identical(revalue(chr, c(A1="B1", A2="B2")), newchr) + # Not relevant for factors because they can't have two levels be the same +}) + +test_that("Mapping with non-matching original levels results in no change, and message", { + expect_message( + expect_identical(revalue(chr, c(A4="B4")), chr)) + expect_message( + expect_identical(revalue(chr, c(A3="B3", A4="B4")), c("A2", "A1", "B3", "A1"))) + + expect_message( + expect_identical(revalue(fac, c(A4="B4")), fac)) + expect_message( + expect_identical(revalue(fac, c(A3="B3", A4="B4")), + factor(c("A1", "A2", "B3"), levels=c("A2", "A1", "B3")))) +}) + +test_that("Swapping values works", { + newchr <- c("A3", "A1", "A2", "A1") + expect_identical(mapvalues(chr, c("A2", "A3"), c("A3", "A2")), newchr) + expect_identical(revalue(chr, c(A2="A3", A3="A2")), newchr) + + newfac <- factor(c("A1", "A3", "A2"), levels=c("A3", "A1", "A2")) + expect_identical(mapvalues(fac, c("A2", "A3"), c("A3", "A2")), newfac) + expect_identical(revalue(fac, c(A2="A3", A3="A2")), newfac) +}) + +test_that("Mapping with ' ' and '$' in original and replacement works", { + chr2 <- c("A2", "A $1", "A3", "A $1") + expect_identical(revalue(chr2, c("A $1"="B $1")), + c("A2", "B $1", "A3", "B $1")) + + fac2 <- factor(c("A $1", "A2", "A3"), levels=c("A2", "A $1", "A3")) + expect_identical(revalue(fac2, c("A $1"="B $1")), + factor(c("B $1", "A2", "A3"), levels=c("A2", "B $1", "A3"))) +}) + +test_that("revalue and mapvalues only accept atomic vectors", { + expect_error(revalue(list(A=3), c("3"=30))) + expect_error(mapvalues(list(A=3), 3, 30)) +}) + +test_that("revalue and mapvalues accept empty vectors and NULL", { + expect_identical(revalue(character(0), c("3"=30), warn_missing=FALSE), character(0)) + expect_identical(mapvalues(character(0), 3, 30, warn_missing=FALSE), character(0)) + + expect_identical(revalue(NULL, c("3"=30), warn_missing=FALSE), NULL) + expect_identical(mapvalues(NULL, 3, 30, warn_missing=FALSE), NULL) +}) + +test_that("revalue and mapvalues respect warn_missing", { + # revalue + expect_message(revalue("a", c("a"="A")), NA) + expect_message(revalue("a", c("b"="B"), warn_missing=TRUE)) + expect_message(revalue("a", c("b"="B"), warn_missing=FALSE), NA) + + # mapvalues + expect_message(mapvalues("a", "a", "A"), NA) + expect_message(mapvalues("a", "b", "B", warn_missing=TRUE)) + expect_message(mapvalues("a", "b", "B", warn_missing=FALSE), NA) + + # mapvalues with factors + expect_message(mapvalues(factor("a"), "a", "A"), NA) + expect_message(mapvalues(factor("a"), "b", "B", warn_missing=TRUE)) + expect_message(mapvalues(factor("a"), "b", "B", warn_missing=FALSE), NA) +}) diff --git a/tests/testthat/test-write_xlsx.R b/tests/testthat/test-write_xlsx.R new file mode 100644 index 0000000..1f48087 --- /dev/null +++ b/tests/testthat/test-write_xlsx.R @@ -0,0 +1,12 @@ +test_that("write_xlsx works", { + d <- data.frame(x = 1:10) %>% data.table() + l <- list(d, d) + write_list2xlsx(l, "d.xlsx", show = FALSE) + + l2 <- read_xlsx2list("d.xlsx") + expect_equal(l2[[1]], d) + + d2 <- read_xlsx("d.xlsx") + expect_equal(d, d2) + # expect_equal(2 * 2, 4) +})