knitr::opts_chunk$set(echo = TRUE)
What are we doing here?
Did we change something recently that's important to note?
For the sake of repeatability, we set the seed here, arbitrarily choosing 123 as our seed. Commenting this code out will mean that each time the script is re-run, random numbers will be different.
set.seed(123)
library(viridis) #package for colors library(here) #package for handling file paths easily library(beepr) #package for making sound to let me know things are done. Not important for document compile, but useful for running time-consuming loops or tasks.
## This is a function script for generating a template readme file for file descriptions in the current folder, labeled README-file.txt. ## It will recursively look through all subfolders of the working directory, and generate a nested list of all folders and files, for easy listing of file descriptions. ## If README-file.txt exists, it will update the README-file.txt with any changes to files or directories (adding or removing). ## In doing so, it use ;\n as an ending sequence - ## multi-line file descriptions are fine so long as they are inside the ; ## The first two lines of the readme file must be left alone. ## To create a clean readme file (not merge descriptions), give argument "overwrite=TRUE" ## The exclude argument uses regular expressions to identify types of filepaths to ignore when making the readme file. ## By default it excludes Rmarkdown compiling folders. You can add more patterns to exclude. ## Usage example: ## setwd(C:/Dropbox/academia/currentproject) ## readme_maker() ## ** now go fill in the text file ** require(readtext) require(stringr) readme_maker=function(exclude=c(".*_files/",".*_cache/"), #Rmarkdown creates these folders, we don't want to list them all. ## You can add your own patterns to exclude - uses regular expressions overwrite=FALSE #if TRUE, will NOT merge with existing readme file ){ #Make list of files, remove those that match "exclude" criterion fileslist=list.files(recursive=T) ind.ignore=NULL; for(cur.exclude in exclude){ ind.ignore=c(ind.ignore, grep(cur.exclude, fileslist)) } fileslist=fileslist[-ind.ignore] ## generate file path list plus header temp=c("## Usage: describe file between colon and semicolon. Multi-line descriptions okay. Duplicate files in different folders are distinguished with [a], [b], etc. ##", "", "Project Description", fileslist) ## set index, skipping header i=4 ## generate obect to store current file path path.cur=NULL ## Loop through all for(count in 4:length(temp)){ #Define current string test.sub=temp[i] #Walk down current file path path.new=NULL do.pathcheck=T #flag for walking down filepath i.path=1 #index for subfolder number depth=0 #to generate appropriate spacing ## Loop through current file path, use the part that fits new file. while(do.pathcheck & i.path<=length(path.cur)){ ## is file in this iteration of subfolders? present=grepl(paste("^", path.cur[i.path], "/", sep=""), test.sub) if(present) { # if it is #update our new filepath path.new=c(path.new, path.cur[i.path]) #update our depth counter depth=depth+1 #eat this subfolder from the current file test.sub=gsub(paste("^", path.cur[i.path], "/", sep=""), "", test.sub) #update index for subfolder i.path=i.path+1 }else{ #if not, stop this checking do.pathcheck=FALSE } } #set current path to our newly calculated one path.cur=path.new #Walk downward along our current file, adding subdirectories as needed while(str_count(test.sub,"/")>0){ #if still has subfolders #find name of this subfolder fold=gsub("/.*", "", test.sub) #update depth count depth=depth+1 #update vector of files to include subfolder temp=c(temp[1:(i-1)], paste(strrep(" ",depth),fold), temp[i:length(temp)]) #update index of vector of files i=i+1 #update current file path path.cur=c(path.cur, fold) #update current file to eat subfolder name test.sub=gsub(paste(fold, "/", sep=""),"", test.sub) } # when we're done eating subfolders # update the current file to be indented, no subfolders in name temp[i]=paste(strrep(" ", depth+1), test.sub, sep="") #update index i=i+1 # } } ## general filepath structure is now complete # add : and spaces to our filepath labs.nocolon=1:2 #lines to exclude: methods description labs=c(temp[labs.nocolon],sprintf("%s : ",temp[-labs.nocolon])) for(lab.cur in labs){ ind=which(labs==lab.cur) if(length(ind)>1){ labs[ind]= sprintf("%s[%s] : ",gsub(" : $","",labs[ind]),letters[1:length(ind)]) } } ## Handle merging with existing file, if present. if(file.exists("README-files.txt") & !overwrite){ #read in file t=readtext("README-files.txt") #remove header stuff tempstore=strsplit(t$text, "##\n\n")[[1]] #separate using ;\n to accomodate multi-line descriptions raw=strsplit(tempstore[2], ";\n")[[1]] rawtemp=labs #create vector from existing file that includes only parts that would match with our labs rawmatch=gsub(": .*",": ",raw) #for each line of existing file, replace base filepath with the existing one (including user descriptions) for(i in 1:length(rawmatch)){ cur.line=rawmatch[i] rawtemp[rawtemp==cur.line]=raw[i] } #save file cat(rawtemp[labs.nocolon], file="README-files.txt", sep="\n") cat(rawtemp[-labs.nocolon], file="README-files.txt", sep=";\n", append = T) }else{ #save file cat(labs[labs.nocolon], file="README-files.txt", sep="\n") cat(labs[-labs.nocolon], file="README-files.txt", sep=";\n", append = T) } }
## function for turning DOY to month-day for visualization doy_2md=function(i){ ymd=as.Date(i-1, origin="2019-01-01") return(format(ymd, "%B %d")) } ## example usage: # #generate 30 observations from day of year 40 to 150 # doy=sample(40:150,30) # #generate gaussian counts with noise # count=exp(-(doy-100)^2/100)+(runif(30)-.5)*.1 # plot(doy,count) # # now plot with day-month references # plot(doy,count, xaxt="n") # #Make sequence of days to label. Here, 5 days from day 40 to 150 # at=round(seq(40,150, length=5)) # axis(1,at=at, labels=doy_2md(at))
## Function for making color gradient in R color_gradient <- function(x, colors=viridis(256), colsteps=100) { return( colorRampPalette(colors) (colsteps) [ findInterval(x, seq(min(x),max(x), length.out=colsteps)) ] ) } ## Example usage: #x=runif(100) #plot(x=x, y=1/x, pch=19,col=color_gradient(x), # cex.lab=1.6, main="Example of color gradient")
## function for making semi-transparent colors t_col <- function(color, alpha = 1, name = NULL) { # color = color name # alpha = fraction of opacity # name = an optional name for the color ## Get RGB values for named color rgb.val <- col2rgb(color) ## Make new color using input color as base and alpha set by transparency t.col <- rgb(rgb.val[1], rgb.val[2], rgb.val[3], max = 255, alpha = alpha*255, names = name) ## Save the color invisible(t.col) } ## example usage: # library(plotrix) #plot(c(1,2),c(1,2),type='l') #red.t = t_col(color="red", alpha=.5) #draw.circle(x=1.5, y=1.5, radius=.2, col=red.t)
## Functions for making pair plots panel.hist <- function(x, ...){ # histogram function usr <- par("usr"); on.exit(par(usr)) par(usr = c(usr[1:2], 0, 1.5) ) h <- hist(x, plot = FALSE, breaks=20) breaks <- h$breaks; nB <- length(breaks) y <- h$counts; y <- y/max(y) rect(breaks[-nB], 0, breaks[-1], y, col = "cyan", ...) } panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor, ...){ # function to plot pairwise correlations usr <- par("usr"); on.exit(par(usr)) par(usr = c(0, 1, 0, 1)) r <- abs(cor(x, y, use="complete.obs")) rsigned=cor(x, y, use="complete.obs") p = cor.test(x, y, use="complate.obs")$p.value txt <- format(c(rsigned, 0.123456789), digits = digits)[1] txt <- paste0(prefix, txt) if(missing(cex.cor)) cex.cor <- 0.8/strwidth(txt) col="grey" if(p<.1){col="black"} if(p<.05){col="blue"} text(0.5, 0.5, txt, cex = cex.cor *(r+.2)/(r+1), col=col) } panel.cortest = function(x,y, digits=2, prefix="", cex.cor, ...){ #function to plot p value of correlations usr <- par("usr"); on.exit(par(usr)) par(usr = c(0, 1, 0, 1)) p <- signif(cor.test(x, y, use="complete.obs")$p.value,2) if(missing(cex.cor)) cex.cor <- 2 col="grey" if(p<.1){col="black"} if(p<.05){col="blue"} text(.5, .5, p, cex=cex.cor, col=col) } ## example usage: # x=runif(100) # dat=data.frame(x=x,y=x+.5+rnorm(100)*.1, z=x + rnorm(100)) # pairs(dat, # lower.panel=panel.cor, # diag.panel=panel.hist) # pairs(dat, # lower.panel=panel.cortest, # diag.panel=panel.hist, # upper.panel=panel.cor) ## Function for taking a vector of strings in R and displaying it as bullets in Rmarkdown ## Note that the chunk needs to be given the argument of results='asis'
``` {r printer} printer=function(x){ ## x needs to be a vector of strings. com=as.character(x) com=com[com!=""] com=gsub("\n","",com) cat(paste('-', com), sep = '\n') }
```r
## Function for making figs with metadata. Note: you will want to change figfold and scriptname default values to be appropriate for this document.
fig_starter=function(filename, #name of figure file to save as WITHOUT SUFFIX
description, #vector of strings, each will be put in its own line of meta file
## Note: generating file is defined in the function, date and time is automatically added.
##default figure info:
width=12,
height=8,
units="in",
res=300,
figfold="5_figs",
scriptname="BCB_analysis_v1.0.Rmd"
){
#function to automate making a jpeg figure (can change code here to make png)
#and also add meta text
#NOTE: still have to use dev.off() at the end of plot-making
## save meta file
cat(c(description,
"",##easy way to add an extra line to separate description for basic data.
paste("from",scriptname),
as.character(Sys.time())),
sep="\n",
file=here(figfold, paste(filename,"_meta.txt", sep=""))
)
## open jpeg device
jpeg(file=here(figfold,paste(filename,".jpg", sep="")),
width=width,
height=height,
units=units,
res=res)
}
## Example usage:
# fig_starter(filename="testfig", description=c("This figure was made as an example.","We can add endless lines of description."))
# plot(1:10,1:10, pch=1:10)
# dev.off()
## Note: in this case the example will not work for you unless you give it the correct location for "figfold" - the relative file path to the folder for your figures.
# function for saving ggplot figures and metadata. As fig_starter (which is for base graphics), except that saving ggfigures is inherently cleaner, as you are not feeding commands to an open graphics device gfig_saver=function(gfig, #object to be saved filename, #name of figure file to save as WITHOUT SUFFIX description, #vector of strings, each will be put in its own line of meta file ## Note: generating file is defined in the function, date and time is automatically added. ##default figure info: width=12, height=8, units="in", figfold="5_figs", scriptname="BCB_analysis_v1.2.Rmd" ){ ## save meta file cat(c(description, "",##easy way to add an extra line to separate description for basic data. paste("from",scriptname), as.character(Sys.time())), sep="\n", file=here(figfold, paste(filename,"_meta.txt", sep="")) ) ggsave(filename=here(figfold, paste(filename,".jpg", sep="")), plot=gfig, device="jpeg", width=width, height=height, units=units ) }
By default, my Rmarkdown files live one folder down from my project directory. The following code creates a skeleton readme file one folder up from the current one (or updates it if it already exists). Cut out all but the readme_maker() lines to create a readme in the current working directory instead of one folder up.
old.wd=getwd()# save current directory setwd("..") #move one folder up readme_maker() #make readme file setwd(old.wd) #move back to previous directory
Reminder: you can have sub-sections tabs using the {.tabset} argument, and can choose which one is on top by default with {.active}:
Maybe here we do some analysis on Site 1. Example plot follows
x=runif(30) y=x+rnorm(30) plot(x,y, main="example plot") out=lm(y~x) abline(out)
Maybe here we do some analysis on Site 2. A different plot follows
x=runif(30) y=3-x+rnorm(30) plot(x,y, main="example plot") out=lm(y~x) abline(out)
Something something insightful comments.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.