Click the Red or Green text to expand or collapse the section
Below is a listing of my R Code. For each entry, I have provided a description, the source code, an example, and if applicable, sample output. The source code and example can be copy and pasted directly into R. To be efficient with space, I collapsed all sections except Description.
This code simplifies the creation of a video in R. It saves a series of images and then invokes the shell to feed the images to a video encoder. It requires the video encoder mencoder. For more, read about it here
Source Code
# ---------------------------
# File: encodeVideo.R
# Author: Shaun Lysen
# Description: This file takes in a plotting function forLoopPlotFnc and a vector
# of values iterVals to iterate over in the plotting function.
encodeVideo <- function(forLoopPlotFnc, iterVals, play=TRUE, fps=25, numDigitsFileNm=4,
encodePath="C:\\\"Program Files\"\\eRightSoft\\SUPER\\mencoder\\mencoder.exe",
playPath="C:\\\"Program Files\"\\eRightSoft\\SUPER\\mencoder\\mplayer.exe") {
# This function creates a video output for a plotting function.
# The two main arguments are forLoopPlotFnc, which is a function that creates a
# plot, and iterVals which is a vector of values to iterate over for the plot.
# For example, if we were graphing a scatterplot for various correlations, with
# the forLoopPlotFnc taking in the correlation as its argument, then iterVals
# will be a vector of all correlations to graph.
# play is a flag to say whether to play the video after it's finished.
# fps gives the number of frames per second for the video.
# !! IMPORTANT !! the encodePath and playPath give the location of the mencoder.exe
# and mplayer.exe files. mencoder is required to encode the file.
# Currently this is just for mpeg4, though mencoder allows many other video formats.
# The code creates jpgs, merges them into a video and then cleans up after itself.
shell("mkdir videoEncodeFolder")
setwd("./videoEncodeFolder")
for(i in 1:length(iterVals)) {
jpeg(paste(getNumberFileName(i, numDigitsFileNm), ".jpg", sep=""))
forLoopPlotFnc(iterVals[i])
dev.off()
}
shell(paste(encodePath, " mf://*.jpg -mf fps=", fps, ":type=jpg -ovc lavc -lavcopts vcodec=mpeg4 -o output.avi 1> nul 2>&1", sep=""))
shell("move output.avi ..")
shell("del *.jpg")
setwd("..")
shell("rmdir videoEncodeFolder")
if(play) {
shell(paste(playPath, "output.avi 1> nul 2>%1"))
}
}
getNumberFileName <- function(number, numDigits=4) {
# This function creates a string with leading 0s for file names.
# This is important because otherwise pic2.jpg comes after pic11.jpg alphabetically.
# If we enforce 4 digits, these become pic0002.jpg and pic0011.jpg and they are
# sorted properly.
if(number > 10^(numDigits))
stop("Not enough Digits for file name")
if(number <= 0)
stop("File number must be positive")
number <- as.integer(number)
numNonZero <- as.integer(log10(number))
numZero <- numDigits - numNonZero - 1
fileNumString <- paste(c(rep("0", numZero), number), sep="", collapse="")
return(fileNumString)
}
Example
# Set up the initial data
datax <- rnorm(100)
dataz <- resid(lm(rnorm(100)~datax))
datax <- (datax-mean(datax))/sd(datax)
dataz <- (dataz - mean(dataz))/sd(dataz)
plotxycor <- function(corr) {
# Plotting function for the for loop
r <- corr
xlim <- c(-3.5,3.5)
ylim <- c(-3.5,3.5)
slope <- 2*(r>=0) - 1
x <- datax
y <- r*datax+sqrt(1-r^2)*dataz
plot(x, y, xlim=xlim, ylim=ylim, pch=19, cex=1, col="blue",
main=paste("r = ", round(r, 4), "\n"))
abline(lm(y~x), col="red", lwd=2)
lines(1.5*ellipsePoints(r), col="black", lwd=3, lty=2)
abline(0, slope, col="green3", lwd=3)
}
ellipsePoints <- function(r, npts=500) {
# This function adds the ellipse to the plot depending on the given correlation
pts <- 1:npts/npts*2*pi
xEll <- sqrt((1+r))*cos(pts)
yEll <- sqrt((1-r))*sin(pts)
ellTmp <- cbind(xEll, yEll)
secAxis <- c(1, -1)
coorMat <- cbind(c(1,1), secAxis)
return(ellTmp %*% coorMat)
}
source("encodeVideo.R")
corrIter <- c(0:100, 99:-100, -99:0)/100
encodeVideo(plotxycor, corrIter)