This is a list of handy R code functions and snippets for some very diverse applications.
Sometimes it's good to actually see the colour palette in an image rather than as a vector of character strings, especially when those strings are hex codes.
The following function uses the legend() function to display the colour palette with their colour names/strings. It tries to scale the legend to fit the number of colours in the palette. The only output is a blank plot showing just the legend.
showpal <- function(
ncol = 2,
cex=1.4,
pt.cex=4
)
{ lp0 <- length(palette())
xspac <- pt.cex/5
yspac <- 2*(pt.cex/5)
if(lp0>12&ncol==2) { # trying to fit longer palettes - needs work
ncol <- ceiling(lp0/6)
cex <- 24/lp0
pt.cex <- 72/lp0
xspac <- pt.cex/2
yspac <- 1.25*(pt.cex/2.5)
}
par(mar=rep(0.5,4))
plot(c(0,1),c(0,1), type="n", bty="n", ann = F,
xaxt="n", yaxt="n", xlab="", ylab="")
legend("center", ncol = ncol, bty = "n",
legend=paste(paste0(seq(1,length(palette())),"."),
palette()),
title = "Current colour palette",
pt.bg = seq(1,length(palette())),
pch = 22,
pt.cex = pt.cex,
cex = cex,
x.intersp = xspac,
y.intersp = yspac)
par(mar = c(4,4,3,1))
}
palette(c("black",rainbow(14, v=0.8, end=0.8),"gray64","white","transparent"))
showpal()
This is a specialist thing -- the xrdml format is a common way of storing the results of X-Ray Diffraction scans (we use a Panalytical Aeris).
There are two versions of the code:
Probably these could be combined in a later version, with the type of output specified by the function options!
xrdml2df <- function(xfile,
xdir = "wd"
) {
if(xdir == "wd") {
xdir <- getwd()
}
xrdmlRaw <- readLines(paste0(xdir, xfile))
twothet0 <- grep("2Theta", xrdmlRaw)
beg0 <- xrdmlRaw[twothet0 + 1]
beg0 <- gsub("\t\t\t\t\t<startPosition>", "", beg0)
beg0 <- gsub("</startPosition>", "", beg0)
beg0 <- as.numeric(beg0)
end0 <- xrdmlRaw[twothet0 + 2]
end0 <- gsub("\t\t\t\t\t<endPosition>", "", end0)
end0 <- gsub("</endPosition>", "", end0)
end0 <- as.numeric(end0)
c0 <- grep("<counts", xrdmlRaw)
xrdmlRaw[c0] <- gsub('\t\t\t\t<counts unit="counts">', "", xrdmlRaw[c0])
xrdmlRaw[c0] <- gsub("</counts>", "", xrdmlRaw[c0])
counts <- as.numeric(unlist(strsplit(xrdmlRaw[c0], " ")))
counts2theta <-
data.frame(Angle = seq(beg0, end0, ((end0 - beg0) / (length(counts) - 1))),
Counts = counts)
rm(list = c("xrdmlRaw","twothet0","beg0","end0","c0","counts"))
return(counts2theta)
}
xrdml2csv <- function(xfile,
xdir = "wd",
toscreen = FALSE
) {
if(xdir == "wd") {
xdir <- getwd()
}
xrdmlRaw <- readLines(paste0(xdir, xfile))
twothet0 <- grep("2Theta", xrdmlRaw)
beg0 <- xrdmlRaw[twothet0 + 1]
beg0 <- gsub("\t\t\t\t\t<startPosition>", "", beg0)
beg0 <- gsub("</startPosition>", "", beg0)
beg0 <- as.numeric(beg0)
end0 <- xrdmlRaw[twothet0 + 2]
end0 <- gsub("\t\t\t\t\t<endPosition>", "", end0)
end0 <- gsub("</endPosition>", "", end0)
end0 <- as.numeric(end0)
c0 <- grep("<counts", xrdmlRaw)
xrdmlRaw[c0] <- gsub('\t\t\t\t<counts unit="counts">', "", xrdmlRaw[c0])
xrdmlRaw[c0] <- gsub("</counts>", "", xrdmlRaw[c0])
counts <- as.numeric(unlist(strsplit(xrdmlRaw[c0], " ")))
counts2theta <-
data.frame(Angle = seq(beg0, end0, ((end0 - beg0) / (length(counts) - 1))),
Counts = counts)
cfile <- paste0(substr(xfile,1,str_locate(xfile,".xrdml")[1]),"csv")
write.csv(counts2theta, file = cfile, row.names = FALSE)
rm(list = c("xrdmlRaw","twothet0","beg0","end0","c0","counts"))
if(toscreen==TRUE) return(counts2theta)
}
Users of Hydrus-1D either need to use the limited graphics in Hydrus itself, open the output files in Excel, or figure out a way of using more flexible software. So here's my code to read the node (Profile) information output files from Hydrus-1D (Nod_Inf.out in the relevant Hydrus project folder) into an R data.frame.
# R code to read Hydrus-1D Nod_Inf.out files into an R data frame
# set Hydrus-1D project directory (folder)
# -=-=-=-=- EDIT THIS TO MATCH THE FOLDER ON YOUR COMPUTER ! -=-=-=-=-
PCdir <- paste0(MyPC,"My Documents/aaTeaching/ENVT5503/Hydrus1D ENVT5503/PRB")
# read Nod_Inf.out file into a vector of character (text) strings
Nod_Inf_out <- readLines(paste0(PCdir,"/","Nod_Inf.out"))
# View(Nod_Inf_out) # optionally check what we just read
# find indices of some rows we want to delete
head_rows <- grep("Node", Nod_Inf_out)
# use indices to delete the rows
Nod_Inf_out <- Nod_Inf_out[-c(seq(1,7),head_rows-2, head_rows-1,
head_rows+1, head_rows+2)]
# find indices of some more rows we want to delete
ends <- grep("end",Nod_Inf_out)[-1*NROW(grep("end",Nod_Inf_out))]
# use indices to delete the rows
Nod_Inf_out <- Nod_Inf_out[-c(ends, ends+1, ends+2)]
# find indices of rows that have the Hydrus-1D print times
time_rows <- grep("Time:", Nod_Inf_out)
# extract the rows with Hydrus-1D print times into a vector
timz <- Nod_Inf_out[time_rows]
# get rid of text around the Hydrus-1D print time values...
timz <- gsub("Time: ","",timz)
timz <- gsub(" ","",timz)
# ...and convert to numbers...
timz <- as.numeric(timz)
# ...then delete the Hydrus-1D print time rows
Nod_Inf_out <- Nod_Inf_out[-c(time_rows)]
# find the rows with column names for each block of print data...
head_rows <- grep("Node", Nod_Inf_out)
# and remove all except the first one
Nod_Inf_out <- Nod_Inf_out[-c(head_rows[-1])]
# strip out all but single spaces from data...
while(NROW(grep(" ", Nod_Inf_out)) > 0) {
Nod_Inf_out <- gsub(" "," ", Nod_Inf_out)
}
# ...and (finally!) delete the very last row (an 'end' statement)
Nod_Inf_out <- Nod_Inf_out[-1*NROW(Nod_Inf_out)]
#
# write the edited output to a file...
writeLines(Nod_Inf_out, con="./NodInf3.out")
# ...and read the file in as space-delimited
node_data <- read.table(file = "NodInf3.out", header = TRUE, sep = " ")
# the is a blank column 1; rename it to "Time"
colnames(node_data)[1] <- "Time"
# use the print times vector to make a vector with
# the relevant time repeated for each block
timz0 <- rep(timz[1], NROW(node_data)/NROW(timz))
for (i in 2:NROW(timz)) {
timz0 <- append(timz0, rep(timz[i], NROW(node_data)/NROW(timz)))
}
# replace the Time colum with the vector we just made...
node_data$Time <- timz0
# ...and convert Time to a factor
node_data$Time <- as.factor(node_data$Time)
# remove temporary objects...
rm(list = c("i","head_rows","Nod_Inf_out","timz","timz0","ends"))
# ...and check the cleaned-up data
str(node_data)
## 'data.frame': 707 obs. of 14 variables:
## $ Time : Factor w/ 7 levels "0","80","160",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ Node : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Depth : num 0 -20 -40 -60 -80 -100 -120 -140 -160 -180 ...
## $ Head : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Moisture : num 0.43 0.43 0.43 0.43 0.43 0.43 0.43 0.43 0.43 0.43 ...
## $ K : num 25 25 25 25 25 ...
## $ C : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Flux : num -2.5 -2.5 -2.5 -2.5 -2.5 ...
## $ Sink : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Kappa : int -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
## $ v.KsTop : num -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 -0.1 ...
## $ Temp : num 20 20 20 20 20 20 20 20 20 20 ...
## $ Conc.1..NS. : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Sorb.1...NS.: num 0 0 0 0 0 0 0 0 0 0 ...
# check it with a plot
# plot as concentration vs. depth
palette(c("black","red3","tomato","gold3","green3",
"blue2","darkcyan", "purple","sienna","gray67"))
par(mar = c(1,4,4,1), mgp = c(1.7,0.3,0), tcl = 0.3, font.lab=2)
plot(node_data$Depth ~ node_data[,13],
type = "l", col = 1,
xlim = c(0, max(node_data[,13], na.rm=T)),
ylim = c(min(node_data$Depth, na.rm=T), 0),
subset = node_data$Time==levels(node_data$Time)[1],
xaxt = "n", xlab = "", ylab = "Depth (cm)")
axis(3)
mtext("Concentration", side = 3, line = 1.7, font = 2)
for (i in 2:nlevels(node_data$Time)) {
points(node_data$Depth ~ node_data[,13], col = i,
subset = node_data$Time==levels(node_data$Time)[i],
type = "o", pch = i-2, cex = 0.6)
}
legend("bottomright", legend = levels(node_data$Time),
col = seq(1,nlevels(node_data$Time)),
pch = c(NA,seq(0,nlevels(node_data$Time))),
lwd = 1,
pt.cex=0.85, bty = "n", inset = 0.02,
title = expression(bold("Time (days)")))
# plot as concentration vs. horizontal distance
par(mar = c(4,4,1,1), mgp = c(1.7,0.3,0), tcl = 0.3, font.lab=2)
node_data$Distance <- -1*node_data$Depth
plot(node_data[,13] ~ -1*node_data$Distance,
type = "l", col = 1,
ylim = c(0, max(node_data[,13], na.rm=T)),
xlim = c(0, max(node_data$Distance, na.rm=T)),
subset = node_data$Time==levels(node_data$Time)[1],
ylab = "Concentration", xlab = "Distance (cm)")
for (i in 2:nlevels(node_data$Time)) {
points(node_data[,13] ~ -1*node_data$Distance, col = i,
subset = node_data$Time==levels(node_data$Time)[i],
type = "o", pch = i-2, cex = 0.6)
}
legend("topright", legend = levels(node_data$Time),
col = seq(1,nlevels(node_data$Time)),
pch = c(NA,seq(0,nlevels(node_data$Time))),
lwd = 1,
pt.cex=0.85, bty = "n", inset = 0.02,
title = expression(bold("Time (days)")))
CC-BY-SA • All content by Ratey-AtUWA. My employer does not necessarily know about or endorse the content of this website.
Created with rmarkdown in RStudio using the cyborg theme from Bootswatch via the bslib package, and fontawesome v5 icons.