core_commons.R 18.5 KB
Newer Older
Holger Brandl's avatar
Holger Brandl committed
1 2 3 4
########################################################################################################################
## set a default cran r mirror  and customize environment

#cat(".Rprofile: Setting Goettingen repository\n")
Holger Brandl's avatar
Holger Brandl committed
5 6
#todo consider to use chooseCRANmirror(graphics=FALSE, ind=10) instead

Holger Brandl's avatar
Holger Brandl committed
7 8 9 10 11 12 13
r = getOption("repos") # hard code the UK repo for CRAN

r["CRAN"] = "http://ftp5.gwdg.de/pub/misc/cran/"
options(repos = r)
rm(r)


## user browser for help
Holger Brandl's avatar
Holger Brandl committed
14
options(help_type = "html")
Holger Brandl's avatar
Holger Brandl committed
15 16

## plot more characters per line
Holger Brandl's avatar
Holger Brandl committed
17
options(width = 100)
Holger Brandl's avatar
Holger Brandl committed
18 19
# options(tibble.width = 110)  ## max width when not using toc
# options( tibble.width = 90) ## max width when using toc
Holger Brandl's avatar
Holger Brandl committed
20

21 22 23
## adjust dplyr printing settings
## http://stackoverflow.com/questions/22471256/overriding-variables-not-shown-in-dplyr-to-display-all-columns-from-df
## http://stackoverflow.com/questions/29396111/dplyrtbl-df-fill-whole-screen
24
# options(dplyr.print_min = 20) ## num rows
Holger Brandl's avatar
Holger Brandl committed
25 26 27
# options(dplyr.width = 130) ## width
# options(tibble.width  = 100)

28
#options(dplyr.width = 250); options(width=250) ## width
29

Holger Brandl's avatar
Holger Brandl committed
30 31 32
# for sqldf to avoid the use of tckl
options(gsubfn.engine = "R")

33 34
## fix annoying column name abbreviations in tibble/pillar
options(pillar.min_title_chars=10000)
Holger Brandl's avatar
Holger Brandl committed
35

Holger Brandl's avatar
Holger Brandl committed
36
########################################################################################################################
Holger Brandl's avatar
Holger Brandl committed
37
## automatic package installation
Holger Brandl's avatar
Holger Brandl committed
38

Holger Brandl's avatar
Holger Brandl committed
39

40
## externalized installer to also allow for installation without loading
41
install_package <- function(x){
Holger Brandl's avatar
Holger Brandl committed
42
    if (! isTRUE(x %in% .packages(all.available = TRUE)) && any(available.packages()[, 1] == x)) {
43
        # update.packages(ask=F) # update dependencies, if any.
Holger Brandl's avatar
Holger Brandl committed
44
        eval(parse(text = paste("install.packages('", x, "')", sep = "")))
45 46 47
    }

    ## if it's still missing check if it's on bioconductor
Holger Brandl's avatar
Holger Brandl committed
48
    if (! isTRUE(x %in% .packages(all.available = TRUE))) {
49 50
        bcPackages <- as.vector(read.dcf(url("https://bioconductor.org/packages/3.3/bioc/src/contrib/PACKAGES"), "Package"))

Holger Brandl's avatar
Holger Brandl committed
51
        if (any(bcPackages == x)) {
52
            source("http://bioconductor.org/biocLite.R")
Holger Brandl's avatar
Holger Brandl committed
53
            eval(parse(text = paste("biocLite('", x, "', ask=FALSE)", sep = "")))
54 55
        }
    }
56 57
}

Holger Brandl's avatar
Holger Brandl committed
58
load_pack <- function(x, warn_conflicts=T){
Holger Brandl's avatar
Holger Brandl committed
59 60
    x <- as.character(substitute(x));

Holger Brandl's avatar
Holger Brandl committed
61
    install_package(x)
Holger Brandl's avatar
Holger Brandl committed
62

63
    ## load it using a library function so that load_pack errors if package is still not ins
Holger Brandl's avatar
Holger Brandl committed
64
    eval(parse(text = paste("base::library(", x, ",  quietly=T, warn.conflicts=", warn_conflicts, ")", sep = "")))
Holger Brandl's avatar
Holger Brandl committed
65 66
}

67

68 69
check_version = function(pkg_name, min_version) {
    cur_version = packageVersion(pkg_name)
Holger Brandl's avatar
Holger Brandl committed
70
    if (cur_version < min_version) stop(sprintf("Package %s needs a newer version,
71 72 73
               found %s, need at least %s", pkg_name, cur_version, min_version))
}
#check_version("dplyr", "0.4-1")
Holger Brandl's avatar
Holger Brandl committed
74

Holger Brandl's avatar
Holger Brandl committed
75
########################################################################################################################
Holger Brandl's avatar
Holger Brandl committed
76
## load core packages
Holger Brandl's avatar
Holger Brandl committed
77

Holger Brandl's avatar
Holger Brandl committed
78 79 80 81 82
#if(!any(.packages(all.available=TRUE)=="biomaRt")){
#    source("http://bioconductor.org/biocLite.R")
#    biocLite("biomaRt", ask=FALSE)
#}

Holger Brandl's avatar
Holger Brandl committed
83 84
#load_pack(plyr)
#load_pack(reshape2)
85
#load_pack(reshape2, quietly=T, warn_conflicts=F)
Holger Brandl's avatar
Holger Brandl committed
86

Holger Brandl's avatar
Holger Brandl committed
87
## load on purpose after plyr
Holger Brandl's avatar
Holger Brandl committed
88
load_pack(purrr)
Holger Brandl's avatar
Holger Brandl committed
89
load_pack(tibble)
Holger Brandl's avatar
Holger Brandl committed
90 91 92
load_pack(dplyr, warn_conflicts = F)
load_pack(magrittr, warn_conflicts = F)
load_pack(tidyr, warn_conflicts = F)
Holger Brandl's avatar
Holger Brandl committed
93 94
load_pack(stringr)
load_pack(readr)
Holger Brandl's avatar
Holger Brandl committed
95
load_pack(forcats)
Holger Brandl's avatar
Holger Brandl committed
96
load_pack(readxl) ## supress differring build number
97

Holger Brandl's avatar
Holger Brandl committed
98
## needed for caching
99
load_pack(digest)
Holger Brandl's avatar
Holger Brandl committed
100 101 102

#suppressWarnings(load_pack(readxl)) ## supress differring build number

103
#load_pack(readxl) ## supress differring build number
104 105 106


## common plotting requirements since they are omnipresent
107
load_pack(ggplot2)
108
load_pack(scales, warn_conflicts = F) # note this has a known conflit with purrr::discard
109
load_pack(grid)
110

Holger Brandl's avatar
Holger Brandl committed
111
## for table exploration without using Rstudio
112
load_pack(DT)
Holger Brandl's avatar
Holger Brandl committed
113

Holger Brandl's avatar
Holger Brandl committed
114 115

## moved into datatable_commons because replaced almost everywhere with dplyr
116
#load_pack(data.table)
Holger Brandl's avatar
Holger Brandl committed
117 118 119 120



########################################################################################################################
Holger Brandl's avatar
Holger Brandl committed
121
#### Convenience aliases
Holger Brandl's avatar
Holger Brandl committed
122 123


Holger Brandl's avatar
Holger Brandl committed
124
echo <- function(...) cat(paste(...), fill = T)
Holger Brandl's avatar
Holger Brandl committed
125 126 127 128

ac <- function(...) as.character(...)

# string concatenation without space gaps (could/should use paste0 instead)
Holger Brandl's avatar
Holger Brandl committed
129 130
## Deprecated: use paste0 instead
#concat <- function(...) paste(..., sep="")
Holger Brandl's avatar
Holger Brandl committed
131 132 133 134 135

unlen <- function(x) length(unique(x))

pp <- function(dat) page(dat, method = "print")

Holger Brandl's avatar
Holger Brandl committed
136 137
# TODO .Deprecated and .Defunct (see http://ropensci.org/blog/technotes/2017/01/05/package-evolution)

Holger Brandl's avatar
Holger Brandl committed
138
# as.df <- function(dt){ warning("DEPRECATED: use as_df instead of as.df"); as.data.frame(dt)}
Holger Brandl's avatar
Holger Brandl committed
139
as_df <- function(dt) as.data.frame(dt)
Holger Brandl's avatar
Holger Brandl committed
140

Holger Brandl's avatar
Holger Brandl committed
141

Holger Brandl's avatar
Holger Brandl committed
142 143 144 145 146
install_package("tibble")

## restore pre-tibble-v1.2 naming to creating data-frame in place
frame_data = function(...) tibble::tribble(...)

147

Holger Brandl's avatar
Holger Brandl committed
148
add_rownames = function(...){ warning("DEPRECATED: Use tibble::rownames_to_column directly"); tibble::rownames_to_column(...)}
149

Holger Brandl's avatar
Holger Brandl committed
150 151 152 153 154 155 156 157 158 159 160 161 162

## redefine dply::splat to allow for more streamlined rowwise df-processing
## see https://groups.google.com/forum/?utm_source=digest&utm_medium=email#!topic/manipulatr/E6WOcHlRJcw
#splat = function (flat) {
#    function(args, ...) {
#        do.call(flat, c(args, list(...)))
#    }
#}
## for now simply import just splat from plyr namespace
install_package("plyr")
splat = plyr::splat


Holger Brandl's avatar
Holger Brandl committed
163 164 165 166 167 168
########################################################################################################################
#### data.frame manipulation


shuffle <- function(df) df[sample(nrow(df)),]

Holger Brandl's avatar
Holger Brandl committed
169
first <- function(x, n=1) head(x, n)
Holger Brandl's avatar
Holger Brandl committed
170
first_group = function(x, which=1) x %>% nest %>% slice(which) %>% unnest(data)
Holger Brandl's avatar
Holger Brandl committed
171 172 173



Holger Brandl's avatar
Holger Brandl committed
174
vec_as_df <- function(namedVec, row_name="name", value_name="value"){
Holger Brandl's avatar
Holger Brandl committed
175
    data_frame(name = names(namedVec), value = namedVec) %>% set_names(row_name, value_name)
Holger Brandl's avatar
Holger Brandl committed
176
}
Holger Brandl's avatar
Holger Brandl committed
177

Holger Brandl's avatar
Holger Brandl committed
178

Holger Brandl's avatar
Holger Brandl committed
179
column2rownames <- function(df, colname){
180
    warning("DEPRECATED: Use tibble::column_to_rownames directly")
181
    #browser()
Holger Brandl's avatar
Holger Brandl committed
182
    ## force into df to avoid dplyr problems
Holger Brandl's avatar
Holger Brandl committed
183
    df <- as_df(df)
Holger Brandl's avatar
Holger Brandl committed
184

Holger Brandl's avatar
Holger Brandl committed
185
    rownames(df) <- ac(df[, colname])
Holger Brandl's avatar
Holger Brandl committed
186 187 188 189
    df[colname] <- NULL
    return(df)
}

Holger Brandl's avatar
Holger Brandl committed
190 191
## pushing some columns to the end of a data.frame
## TBD how to make this possible without quoting column names?
Holger Brandl's avatar
Holger Brandl committed
192
push_right <- function(df, pushColNames){
Holger Brandl's avatar
Holger Brandl committed
193
    df[, c(setdiff(names(df), pushColNames), pushColNames)]
Holger Brandl's avatar
Holger Brandl committed
194 195 196
}


Holger Brandl's avatar
Holger Brandl committed
197
## pushing some columns to the beginning of a data.frame
Holger Brandl's avatar
Holger Brandl committed
198
push_left <- function(df, pushColNames){
Holger Brandl's avatar
Holger Brandl committed
199
    df[, c(pushColNames, setdiff(names(df), pushColNames))]
Holger Brandl's avatar
Holger Brandl committed
200 201 202
}


Holger Brandl's avatar
Holger Brandl committed
203
#http://astrostatistics.psu.edu/datasets/R/html/base/html/formals.html
204 205 206 207 208
## conflicts with purrr::set_names but does not work with ....
set_names <- function(df, ...){
    newnames <- as.character(unlist(list(...)))

    ## automatically convert matrices to data.frames (otherwise the names set would fail
209
    if (is.matrix(df))df %<>% as.data.frame()
210 211 212 213

    names(df) <- newnames;
    return(df)
}
214 215 216
# iris %>% purrr::set_names(paste(names(iris), "__")) %>% glimpse
# iris %>% set_names(paste(names(iris), "__")) %>% glimpse
#
Holger Brandl's avatar
Holger Brandl committed
217 218
#iris %>% set_names(c("setosa", "hallo")) %>% head
#iris %>% set_names("setosa", "hallo") %>% head
Holger Brandl's avatar
Holger Brandl committed
219 220


221
# devtools::source_url("https://www.dropbox.com/s/r6kim8kb8ohmptx/core_commons.R?dl=1")
222

223 224
pretty_names = function(some_names, make_unique=FALSE){
    new_names = some_names %>%
225
        str_replace_all("[#+=.,()/*: -]+", "_") %>%
226 227
        str_replace(fixed("["), "") %>%
        str_replace(fixed("]"), "") %>%
Holger Brandl's avatar
Holger Brandl committed
228
    ## remove leading and tailing underscores
229 230
        str_replace("[_]+$", "") %>%
        str_replace("^[_]+", "") %>%
Holger Brandl's avatar
Holger Brandl committed
231
    ## remove unicode characters
232
        iconv(to = 'ASCII', sub = '') %>% ## http://stackoverflow.com/questions/24807147/removing-unicode-symbols-from-column-names
233 234 235
        tolower

    if(make_unique){
Holger Brandl's avatar
Holger Brandl committed
236
    ## make duplicates unqiue
237 238 239 240
      new_names %<>% make.unique(sep = "_")
    }

    new_names
241
}
242

243
pretty_columns = function(df){
244
    names(df) <- names(df) %>% pretty_names(make_unique=TRUE)
245 246
    df
}
Holger Brandl's avatar
Holger Brandl committed
247

248 249
# http://stackoverflow.com/questions/23188900/view-entire-dataframe-when-wrapped-in-tbl-df
print_all <- function(df) df %>% tbl_df %>% print(n = nrow(.))
Holger Brandl's avatar
Holger Brandl committed
250

Holger Brandl's avatar
Holger Brandl committed
251 252 253
head_html <- function(df, n=5) head(df, n) %>%
    knitr::kable(format = "html") %>%
    print()
Holger Brandl's avatar
Holger Brandl committed
254

Holger Brandl's avatar
Holger Brandl committed
255 256
print_head <- function(df, desc=NULL){
    print(head(df))
Holger Brandl's avatar
Holger Brandl committed
257
    print(nrow(df))
Holger Brandl's avatar
Holger Brandl committed
258 259 260 261 262
    return(df)
}


fac2char <- function(mydata, convert=names(mydata)[sapply(mydata, is.factor)]){
Holger Brandl's avatar
Holger Brandl committed
263
    if (length(convert) == 0) {
Holger Brandl's avatar
Holger Brandl committed
264 265
        return(mydata)
    }
Holger Brandl's avatar
Holger Brandl committed
266 267 268

    inputColOrder <- names(mydata)

Holger Brandl's avatar
Holger Brandl committed
269
    convertData <- subset(mydata, select = names(mydata) %in% convert)
Holger Brandl's avatar
Holger Brandl committed
270 271
    convertData <- as.data.frame(lapply(convertData, as.character), stringsAsFactors = FALSE)

Holger Brandl's avatar
Holger Brandl committed
272
    keepData <- subset(mydata, select = ! (names(mydata) %in% convert))
Holger Brandl's avatar
Holger Brandl committed
273
    newdata <- cbind(convertData, keepData)
Holger Brandl's avatar
Holger Brandl committed
274
    newdata <- newdata[, inputColOrder]
Holger Brandl's avatar
Holger Brandl committed
275 276 277 278

    return(newdata)
}

Holger Brandl's avatar
Holger Brandl committed
279 280 281 282
## convenience method to sort factor levels with decreasing frequencies
fct_revfreq = function(x) fct_infreq(x) %>% fct_rev


Holger Brandl's avatar
Holger Brandl committed
283
## replace R within pipe change just use ... %>% do(replaceNA(0)) %>% ...
284 285 286 287 288 289 290
replaceNA <- function(x, withValue) {
    warning("DEPRECATED Use replace_NA instead")
    x[is.na(x)] <- withValue
    x
}

replace_NA <- function(x, withValue) { x[is.na(x)] <- withValue; x}
Holger Brandl's avatar
Holger Brandl committed
291

Holger Brandl's avatar
Holger Brandl committed
292

Holger Brandl's avatar
Holger Brandl committed
293

294 295 296 297 298

## see http://stackoverflow.com/questions/17288222/r-find-value-in-multiple-data-frame-columns/40586572#40586572
## case-insenstive search all columns of a data-frame with a fixed search term
search_df = function(df, search_term){
    apply(df, 1, function(r){
Holger Brandl's avatar
Holger Brandl committed
299
        any(str_detect(as.character(r), fixed(search_term, ignore_case = T)))
300 301 302 303 304 305 306 307 308 309 310 311
    }) %>% subset(df, .)
}


## filter a data-frame for those rows where at least one column is matching the given expression (that must evaluate to a boolean vector for each row).
match_df = function(df, search_expr){
    filter_fun = eval(substitute(function(x){search_expr}))

    apply(df, 1, function(r) any(filter_fun(r))) %>% subset(df, .)
}


Holger Brandl's avatar
Holger Brandl committed
312

Holger Brandl's avatar
Holger Brandl committed
313
## for na instead use mutate_each with:
Holger Brandl's avatar
Holger Brandl committed
314 315 316
#empty_as_na <- function(x) safe_ifelse(x=="", NA, x)
#empty_as_na <- function(x) ifelse(class(x)  %in% c("factor", "character") & x=="", NA, x)
empty_as_na <- function(x){
Holger Brandl's avatar
Holger Brandl committed
317 318
    if ("factor" %in% class(x))x <- as.character(x) ## since ifelse wont work with factors
    ifelse(as.character(x) != "", x, NA)
Holger Brandl's avatar
Holger Brandl committed
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
}

#if(F){ ## DEBUG of empty_as_na
#cond <- allJobs %>% head %$% submit_time %>% c("")
#empty_as_na( cond)
#cond <- allJobs %>% head %$% resubmission_of
#empty_as_na( cond)
#
#empty_as_na( c(1, 2, NA))
#empty_as_na( c("sdf", "sdf2", NA))
#empty_as_na( c("sdf", "sdf2", ""))
#
#myFac <- as.factor(c("sdf", "sdf2", NA))
#empty_as_na( myFac)
#ifelse(as.character(myFac)!="", myFac, NA)
#
#empty_as_na( c("sdf", "sdf2", ""))
#
#iris[1,1] <- ""
#apply(iris, 2, function(x) gsub("^$|^ $", NA, x))
#}


Holger Brandl's avatar
Holger Brandl committed
342 343 344
## see http://stackoverflow.com/questions/24172111/change-the-blank-cells-to-na/33952598#33952598


Holger Brandl's avatar
Holger Brandl committed
345 346 347 348 349 350
## apply dplyr::filter to df but use filter criterions for cross-tabulation beforehand
filter_count <- function(df, ...){
    print(count(df, ...))
    filter(df, ...)
}

351

352
n_as = function(df, name){
Holger Brandl's avatar
Holger Brandl committed
353 354 355 356
    names(df)[length(names(df))] = name
    df
}

Holger Brandl's avatar
Holger Brandl committed
357 358
#count_occ = function(df, ...) count(df, ...) %>% n_as("num_occ")

Holger Brandl's avatar
Holger Brandl committed
359 360 361
dcount = function(df, ...) count(df, ...) %>%
    n_as("num_occ") %>%
    count(num_occ)
Holger Brandl's avatar
Holger Brandl committed
362

Holger Brandl's avatar
Holger Brandl committed
363
count_as = function(df, n_name, ...) count(df, ...) %>% n_as(n_name)
Holger Brandl's avatar
Holger Brandl committed
364 365 366 367 368
#iris %>% count_as("num_occ", Species)
#iris %>% dcross_tab(Species)



Holger Brandl's avatar
Holger Brandl committed
369

Holger Brandl's avatar
Holger Brandl committed
370
distinct_all = function (x, ...) distinct(x, ..., .keep_all = T)
Holger Brandl's avatar
Holger Brandl committed
371

Holger Brandl's avatar
Holger Brandl committed
372 373 374 375 376 377
#' Return <code>true</code> if the data.frame is distinct with respect to the provided unqoted variabled names/expressions
is_distinct = function(x, ...){
    distinct(x) %>% nrow == nrow(x)
}


Holger Brandl's avatar
Holger Brandl committed
378 379 380 381
## fetch a column of a matrix in a magrittr pipe. Useful along with str_*
get_col = function(data, col_index) data[, col_index] ## also could use magrittr::extract here


Holger Brandl's avatar
Holger Brandl committed
382
## convience method to extract a column, defaults to _ as separator and the first column
Holger Brandl's avatar
Holger Brandl committed
383
extract_col = function(x, col_index=1, sep="_", num_cols=10){ str_split_fixed(x, sep, num_cols)[, col_index]}
Holger Brandl's avatar
Holger Brandl committed
384 385


Holger Brandl's avatar
Holger Brandl committed
386 387 388 389 390 391 392 393 394
## Extract the first group of a grouped data-frame
first_group = function(groupedDF){
    # groupedDF = geneLists
    # groupedDF = iris %>% group_by(Species)
    # https://stackoverflow.com/questions/33775239/emulate-split-with-dplyr-group-by-return-a-list-of-data-frames
    (groupedDF %>% do(data = (.)) %$% map(data, identity))[[1]]
}


Holger Brandl's avatar
Holger Brandl committed
395
mutate_inplace <- function(data, var, expr){
Holger Brandl's avatar
Holger Brandl committed
396
    load_pack("rlang")
Holger Brandl's avatar
Holger Brandl committed
397 398 399 400 401 402

    var <- enexpr(var)
    var_name <- quo_name(var)
    expr <- enexpr(expr)

    call <- quo(UQ(var) %>% UQ(expr))
Holger Brandl's avatar
Holger Brandl committed
403
    # print(call)
Holger Brandl's avatar
Holger Brandl committed
404 405 406 407 408 409
    mutate(data, !!var_name := UQ(call))
}

# mutate_inplace( iris, Species, str_replace("vir", "foo") )


Holger Brandl's avatar
Holger Brandl committed
410

411 412 413 414 415 416 417
reload_dplyr <- function(){
    unloadNamespace('tidyr')
    unloadNamespace('dplyr')
    require(tidyr);require(dplyr)
}


418
## from http://stackoverflow.com/questions/7505547/detach-all-packages-while-working-in-r
419
unload_packages <- function() {
Holger Brandl's avatar
Holger Brandl committed
420 421 422 423
    basic.packages <- c("package:stats", "package:graphics", "package:grDevices", "package:utils", "package:datasets", "package:methods", "package:base")
    package.list <- search()[ifelse(unlist(gregexpr("package:", search())) == 1, TRUE, FALSE)]
    package.list <- setdiff(package.list, basic.packages)
    if (length(package.list) > 0)for (package in package.list) detach(package, character.only = TRUE)
424
}
Holger Brandl's avatar
Holger Brandl committed
425 426


Holger Brandl's avatar
Holger Brandl committed
427 428 429 430
## workaround for biomart
## Deprecated: load dplyr after biomart to avoid this problem
#dselect <- function(...) dplyr::select(...)

Holger Brandl's avatar
Holger Brandl committed
431

Holger Brandl's avatar
Holger Brandl committed
432
########################################################################################################################
Holger Brandl's avatar
Holger Brandl committed
433
#### Result Caching for long running tasks
Holger Brandl's avatar
Holger Brandl committed
434

Holger Brandl's avatar
Holger Brandl committed
435 436
## related: http://cran.r-project.org/web/packages/R.cache/R.cache.pdf

437
cache_it <- function(expr, filePrefix="cache"){
Holger Brandl's avatar
Holger Brandl committed
438
    cacheFile <- paste0(filePrefix, "_", substr(digest::digest(deparse(expr)), 1, 6)) %>% paste0(".", ., ".RData")
Holger Brandl's avatar
Holger Brandl committed
439

Holger Brandl's avatar
Holger Brandl committed
440
    if (file.exists(cacheFile)) {
Holger Brandl's avatar
Holger Brandl committed
441 442 443
        local(get(load(cacheFile)))
    } else {
        result <- eval(expr)
Holger Brandl's avatar
Holger Brandl committed
444
        save(result, file = cacheFile)
Holger Brandl's avatar
Holger Brandl committed
445 446 447 448 449 450
        result
    }
}

## Examples
#mydata <- quote(iris %>% filter(Species=="setosa")) %>% cache_it("tt")
Holger Brandl's avatar
Holger Brandl committed
451 452
#mydata <- quote(iris %>% filter(Species=="setosa")) %>% cache_it()
#mydata <- quote( { print("evaluate expr"); iris %>% filter(Species=="setosa") } ) %>% cache_it()
Holger Brandl's avatar
Holger Brandl committed
453 454 455 456

########################################################################################################################
#### File System

Holger Brandl's avatar
Holger Brandl committed
457
is.directory <- function(dirname) ! is.na(file.info(dirname)$isdir)
Holger Brandl's avatar
Holger Brandl committed
458 459 460


mcdir <- function(dirname){
Holger Brandl's avatar
Holger Brandl committed
461
    if (! file.exists(dirname)) {
Holger Brandl's avatar
Holger Brandl committed
462 463 464 465 466 467 468 469 470
        dir.create(dirname)
    }

    setwd(dirname)
}

locload <- function(fileName) local(get(load(fileName)))


Holger Brandl's avatar
Holger Brandl committed
471
## tbd: it would be more efficient to use Reduce here (see http://stackoverflow.com/questions/34344214/how-to-join-multiple-data-frames-using-dplyr)
Holger Brandl's avatar
Holger Brandl committed
472 473
rmerge <- function(LDF, by, ...){
    DF <- LDF[[1]]
Holger Brandl's avatar
Holger Brandl committed
474 475
    for (i in 2 : length(LDF)) {
        DF <- merge(DF, LDF[[i]], by = by)
Holger Brandl's avatar
Holger Brandl committed
476 477 478 479 480
    }
    DF
}


481 482
trim_ext <- function(fileNames, ...){
    for (fileExt in list(...)) {
Holger Brandl's avatar
Holger Brandl committed
483
        fileNames <- str_replace(fileNames, paste(fileExt, "$", sep = ""), "")
Holger Brandl's avatar
Holger Brandl committed
484 485 486 487 488 489
    }

    fileNames
}


Holger Brandl's avatar
Holger Brandl committed
490
rmSomeElements <- function(vec, toDel) vec[! (vec %in% toDel)]
Holger Brandl's avatar
Holger Brandl committed
491

Holger Brandl's avatar
Holger Brandl committed
492
rmLastElement <- function(vec) vec[- length(vec)]
Holger Brandl's avatar
Holger Brandl committed
493 494 495 496 497


########################################################################################################################
## Memory management

Holger Brandl's avatar
Holger Brandl committed
498

Holger Brandl's avatar
Holger Brandl committed
499
# improved list of objects
Holger Brandl's avatar
Holger Brandl committed
500 501
lsos <- function (pos = 1, pattern, order.by, decreasing=FALSE, head=FALSE, n=5) {
    napply <- function(names, fn) sapply(names, function(x) fn(get(x, pos = pos)))
Holger Brandl's avatar
Holger Brandl committed
502
    names <- ls(pos = pos, pattern = pattern)
Holger Brandl's avatar
Holger Brandl committed
503

Holger Brandl's avatar
Holger Brandl committed
504 505 506
    obj.class <- napply(names, function(x) as.character(class(x))[1])
    obj.mode <- napply(names, mode)
    obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
Holger Brandl's avatar
Holger Brandl committed
507
    obj.size <- napply(names, object.size) / 1000000
Holger Brandl's avatar
Holger Brandl committed
508
    obj.dim <- t(napply(names, function(x)
Holger Brandl's avatar
Holger Brandl committed
509

Holger Brandl's avatar
Holger Brandl committed
510
    as.numeric(dim(x))[1 : 2]))
Holger Brandl's avatar
Holger Brandl committed
511 512
    vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
    obj.dim[vec, 1] <- napply(names, length)[vec]
Holger Brandl's avatar
Holger Brandl committed
513

Holger Brandl's avatar
Holger Brandl committed
514 515
    out <- data.frame(obj.type, obj.size, obj.dim)
    names(out) <- c("Type", "Size", "Rows", "Columns")
Holger Brandl's avatar
Holger Brandl committed
516

Holger Brandl's avatar
Holger Brandl committed
517 518
    if (! missing(order.by))
    out <- out[order(out[[order.by]], decreasing = decreasing),]
Holger Brandl's avatar
Holger Brandl committed
519

Holger Brandl's avatar
Holger Brandl committed
520
    if (head)out <- head(out, n)
Holger Brandl's avatar
Holger Brandl committed
521

Holger Brandl's avatar
Holger Brandl committed
522
    out <- transform(out, var_name = rownames(out))
Holger Brandl's avatar
Holger Brandl committed
523 524 525 526
    rownames(out) <- NULL
    arrange(out, Size)
}

Holger Brandl's avatar
Holger Brandl committed
527
# shorthand that just shows top 1 results
Holger Brandl's avatar
Holger Brandl committed
528
lsosh <- function(..., n=10) {
Holger Brandl's avatar
Holger Brandl committed
529
    lsos(..., order.by = "Size", decreasing = TRUE, head = TRUE, n = n)
Holger Brandl's avatar
Holger Brandl committed
530 531
}

Holger Brandl's avatar
Holger Brandl committed
532 533 534 535 536
########################################################################################################################
### Statistics


## outlier handling
Holger Brandl's avatar
Holger Brandl committed
537 538 539
trim_outliers <- function(values, probs=c(0.05, 0.95)){
    values = deResults$pvalue
    stopifnot(length(probs) == 2)
540
    quantiles = quantile(values, probs, na.rm = TRUE)
Holger Brandl's avatar
Holger Brandl committed
541 542 543

    pmax(quantiles[1], pmin(quantiles[2], values))
}
Holger Brandl's avatar
Holger Brandl committed
544 545 546 547

## use trim_outliers instead
#limit_range <- function(values, range)  pmax(range[1], pmin(range[2], values))

Holger Brandl's avatar
Holger Brandl committed
548
se <- function(x) sd(x, na.rm = TRUE) / sqrt(sum(! is.na(x)))
549

Holger Brandl's avatar
Holger Brandl committed
550 551 552
# https://stackoverflow.com/questions/43627679/round-any-equivalent-for-dplyr/46489816#46489816
round_any = function(x, accuracy, f=round){f(x/ accuracy) * accuracy}

553 554 555 556 557 558 559

########################################################################################################################
### Misc

## inspired by http://stackoverflow.com/questions/8343509/better-error-message-for-stopifnot
assert <- function (expr, error) {
    if (! expr) stop(error, call. = FALSE)
560 561 562
}

### table rendering
Holger Brandl's avatar
Holger Brandl committed
563
table_browser <- function(df, caption=deparse(substitute(df)), ...){
Holger Brandl's avatar
Holger Brandl committed
564
    datatable(df, filter = "bottom", extensions = 'Buttons', options = list(dom = 'Bfrtip', buttons = c('copy', 'csv', 'excel')), caption = caption, ...)
565
}
566

Holger Brandl's avatar
Holger Brandl committed
567 568 569
#results_prefix = "env_data_prep"
add_prefix = function(filename) {
    ## prefix a name with a project-prefix. Requires that results_prefix to be defined
570 571 572
    prefixName=if_else(str_length(results_prefix)==0, basename(filename), paste0(results_prefix, ".", basename(filename)))

    file.path(dirname(filename), prefixName)
573 574
}

Holger Brandl's avatar
Holger Brandl committed
575 576
## https://stackoverflow.com/questions/18669886/how-to-unfold-user-and-environment-variable-in-r-language/46240642#46240642
interp_from_env = function(path){
577
    # DEBUG path="${genomeFasta}.algncounts.txt"
Holger Brandl's avatar
Holger Brandl committed
578
    e <- new.env()
579
    env = Sys.getenv() %>% purrr::discard(~ str_detect(.x, fixed("()")))
580
    paste0(make.names(names(env)), "='", gsub("'", '', env) %>% str_replace_all(fixed("\\"), ""), "'") %>%
581 582
        map(~eval(parse(text=.), envir=e))
    # (system("export", intern=T) %>% str_split_fixed(" ", 2))[,2] %>% map(~eval(parse(text=.), envir=e))
Holger Brandl's avatar
Holger Brandl committed
583 584 585 586
    glue::glue(path, .envir=e, .open="${")
}

# #usage examples
587
# require(stringr)
Holger Brandl's avatar
Holger Brandl committed
588
# read.delim(interp_from_env("${PRJ_DATA}/foo.txt") )
589
# source(interp_from_env("${HOME}/bar.R"))