[R] error "variable names are limited to 256 bytes" when sourcing code
Erik Iverson
eriki at ccbr.umn.edu
Wed May 26 21:27:49 CEST 2010
Is the '`' character supposed to be there before the ## Add error bars
comment?
If that is the problem, let it be a good lesson to use an editor with
syntax highlighting. :)
Brian Frizzelle wrote:
> All,
>
> I think there may be some misunderstanding about my problem. In my code,
> which is written as an R function, all of my variable names are short. I get
> that error when I try to source the function so I can call it. I just do not
> know why I'm getting the error, especially since I have written other very
> similar functions that all work.
>
> So I have chosen to post the code below. I welcome any ideas about where in
> this code the error is occurring.
>
> ##########################################################
> ### SCRIPT: graph_hh_wealth_function.R
> ### DATE: April 22, 2010
> ### AUTHOR: Brian Frizzelle
> ###
> ### This function draws two line graphs of household-level wealth from a
> variable
> ### in a dataset output from an agent-based model run.
> ###
> ### The two graphs are:
> ### 1) a line graph showing change in Wealth over time for each individual
> ### household
> ### 2) a line graph of summary statistics of Wealth for the households
> (min,
> ### max, mean, and error bars)
> ###
> ### Required Arguments:
> ### * inpath - The path to the directory containing the village-level
> statistics
> ### file
> ### NOTE: Use the UNIX forward slash (/) convention when entering the path
> ### and do not include a slash at the end of the path.
> ### OK: "D:/data"
> ### Not OK: "D:\data"
> ### Not OK: "D:/data/"
> ### * infile - The name of the village-level statistics file
> ### * outpath - The path to the directory where you want the output graphics
> to
> ### be saved
> ### * outpref - The prefix that you want for the output PNG graphics files
> ### NOTE: Do not include underscores (_) or spaces in the output prefix.
> ### Instead, please use dashes (-). Your prefix will be separated
> ### from the remainder of the file names by a dash.
> ###
> ### Optional Arguments:
> ### * log.plot - Logical. Default is FALSE.
> ### If TRUE, then the individual household wealth graph is plotted
> ### with a logarithmic Y-axis.
> ### If FALSE, then the individual household wealth graph is plotted
> ### with a standard Y-axis.
> ### * err.bar - Logical. Default is TRUE.
> ### If TRUE, then error bars of 1 standard deviation will be drawn
> ### around the mean.
> ### If FALSE, then no error bars will be drawn.
> ### * n.quantiles - Integer. Value between 3 and 10. Default is 0, meaning
> no
> ### quantile lines will be drawn.
> ### This is the number of bins into which you would like the variable
> ### separated. One line for each will be drawn, with the exception of
> ### the min and max, which are already drawn.
> ##########################################################
>
> graph.hh.wealth <- function(inpath, infile, outpath, outpref,
> log.plot=FALSE,
> err.bar=TRUE, n.quantiles=0)
>
> {
>
> ##*************************************************
> ## Set the path and name of the input file
> ## - The 'paste' command concatenates the two
> ## - The 'skiplines' var sets the number of lines
> ## to skip when reading in the dataset.
> ##*************************************************
> if (substr(inpath, nchar(inpath), nchar(inpath)) == "/")
> inpath <- substr(inpath, 0, nchar(inpath)-1)
> if (substr(outpath, nchar(outpath), nchar(outpath)) == "/")
> outpath <- substr(outpath, 0, nchar(outpath)-1)
> pathfile <- paste(inpath, infile, sep="/")
> skiplines <- 1
>
> ##*************************************************
> ## Set the names of the output file graphics
> ##*************************************************
> fnout.wlth <- "hhwealth.png"
> fnout.wlthss <- "hhwealth-sumstats.png"
> output.png.wlth <- paste(outpath, "/", outpref, fnout.wlth, sep="")
> output.png.wlthss <- paste(outpath, "/", outpref, fnout.wlthss, sep="")
>
> ##*************************************************
> ## Read in the household-level output dataset
> ##*************************************************
> hhstats <- read.delim(file=pathfile, header=TRUE, sep ="\t", dec=".",
> skip=skiplines)
>
> ##*************************************************
> ## Get some information from the household-level
> ## dataset for use in plotting.
> ## - the village number
> ## - a vector of the unique HH IDs
> ## - the maximum number of model run years
> ## - the maximum wealth among all households
> ##*************************************************
> villnum <- mean(hhstats$V84ID)
> uniq.hh.ids <- unique(hhstats$HHID00)
> max.yr <- max(hhstats$Year)
> max.wlth <- max(hhstats$Wealth)
>
> ##*************************************************
> ## Extract out the vars needed for the individual
> ## household line graph
> ## Vars: Year, HHID00, Wealth, Status
> ##*************************************************
> hh.wealth <- hhstats[,c("Year","HHID00","Wealth","Status")]
> hh.wealth.pos <- hh.wealth[hh.wealth$Wealth >= 0,]
> hh.wealth.plot <- hh.wealth.pos[hh.wealth.pos$Status == 0 |
> hh.wealth.pos$Status == 1,]
>
> ##*************************************************
> ## Get the summary statistics by year for Wealth
> ##*************************************************
> ## Get a list of unique years for iterating
> unqyrlist <- unique(hh.wealth.plot$Year)
>
> ## Determine the divisor for the quantiles
> div.q <- 1.0 / n.quantiles
>
> ## Loop through years to extract summary statistics
> for (yr in min(unqyrlist):max(unqyrlist)) {
> # Get records for current year
> this.yr <- hh.wealth.plot[hh.wealth.plot$Year == yr,]
> # Calc summary statistics by statistic
> this.n <- dim(this.yr)[1]
> this.min <- min(this.yr$Wealth)
> this.max <- max(this.yr$Wealth)
> this.mean <- mean(this.yr$Wealth)
> this.med <- median(this.yr$Wealth)
> this.sd <- sd(this.yr$Wealth)
> this.ebneg <- this.mean-this.sd
> this.ebpos <- this.mean+this.sd
> this.sumstats <- c(yr, this.n, this.min, this.max, this.mean,
> this.med, this.sd, this.ebneg, this.ebpos)
> # Convert vector to 1-row data frame
> this.df <- as.data.frame(t(as.matrix(this.sumstats)))
> colnames(this.df) <- c("Year", "Count", "Min", "Max", "Mean", "Median",
> "SD", "EB.Low", "EB.High")
> # Now, calculate the specified quantiles for this year
> names(yr) <- "Year"
> this.q <- as.data.frame(t(as.matrix(c(
> quantile(this.yr$Wealth, probs=seq(0, 1, div.q)), yr))))
> # Append the data frame to the output data frame
> if (yr == min(unqyrlist)) {
> hh.wealth.plot.ss <- this.df
> hh.wealth.quantiles <- this.q
> } else {
> hh.wealth.plot.ss <- rbind.data.frame(hh.wealth.plot.ss, this.df)
> hh.wealth.quantiles <- rbind.data.frame(hh.wealth.quantiles, this.q)
> }
> }
>
> ##*************************************************
> ## Set up parameters for quantile plots
> ##*************************************************
> q.names <- c("", "", "Terciles", "Quantiles", "Quintiles",
> "Sextiles", "Septiles", "Octiles", "Noniles", "Deciles")
> q.labs <- c("1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th")
> # Determine if median will be plotted
> if (n.quantiles %% 2) plot.med <- FALSE else plot.med <- TRUE
> # Determine which non-median quantile columns will be plotted
> if (n.quantiles %% 2) { # If the number of quantiles is odd
> cols.q <- c(2:n.quantiles)
> } else { # If the number of quantiles is even
> cols.q <- c(2:(n.quantiles/2), (2+(n.quantiles/2)):n.quantiles)
> col.med <- (n.quantiles/2) + 1
> }
>
> ##*************************************************
> ## Set up plotting parameters for the summary
> ## statistics graph
> ##*************************************************
> # Set y axis limits
> ylim.min <- min(hh.wealth.plot.ss)
> ylim.max <- max(hh.wealth.plot.ss)
> # Set title
> ttl.ss <- paste("Summary Statistics of Household Wealth Change Over Time\n
> (Village",
> villnum, ")", sep="")
> # Set legend based on arguments
> leg.txt.ss <- c("Mean", "Min", "Max", "Error Bars", "# of HHs")
> if (err.bars == TRUE & n.quantiles == 0) {
> leg.txt.ss <- c("Mean", "Min", "Max", "Error Bars", "# of HHs")
> leg.lty.ss <- c(1,2,4,5,0)
> leg.lwd.ss <- c(2,1,1,1,0)
> leg.pch.ss <- c(-1,-1,-1,-1,16)
> leg.col.ss <- c("black","darkolivegreen4","chartreuse4","red","blue")
> } else if (err.bars == FALSE & n.quantiles >= 3) {
> if (n.quantiles %% 2) { # Odd number of quantiles
> leg.txt.ss <- c("Mean", "Min", "Max", q.names[n.quantiles], "# of HHs")
> leg.lty.ss <- c(1,2,4,3,0)
> leg.lwd.ss <- c(2,1,1,1,0)
> leg.pch.ss <- c(-1,-1,-1,-1,16)
> leg.col.ss <- c("black","darkolivegreen4","chartreuse4","orange","blue")
> } else { # Even number of quantiles
> leg.txt.ss <- c("Mean", "Min", "Max", "Median", q.names[n.quantiles],
> "# of HHs")
> leg.lty.ss <- c(1,2,4,3,3,0)
> leg.lwd.ss <- c(2,1,1,2,1,0)
> leg.pch.ss <- c(-1,-1,-1,-1,-1,16)
> leg.col.ss <- c("black", "darkolivegreen4", "chartreuse4", "orange",
> "orange", "blue")
> }
> } else if (err.bars == TRUE & n.quantiles >= 3) {
> if (n.quantiles %% 2) { # Odd number of quantiles
> leg.txt.ss <- c("Mean", "Min", "Max", "Error Bars", q.names[n.quantiles],
> "# of HHs")
> leg.lty.ss <- c(1,2,4,5,3,0)
> leg.lwd.ss <- c(2,1,1,1,1,0)
> leg.pch.ss <- c(-1,-1,-1,-1,-1,16)
> leg.col.ss <- c("black", "darkolivegreen4", "chartreuse4", "red",
> "orange",
> "blue")
> } else { # Even number of quantiles
> leg.txt.ss <- c("Mean", "Min", "Max", "Error Bars", "Median",
> q.names[n.quantiles], "# of HHs")
> leg.lty.ss <- c(1,2,4,5,3,3,0)
> leg.lwd.ss <- c(2,1,1,1,2,1,0)
> leg.pch.ss <- c(-1,-1,-1,-1,-1,-1,16)
> leg.col.ss <- c("black", "darkolivegreen4", "chartreuse4", "red",
> "orange",
> "orange","blue")
> }
> } else {
> leg.txt.ss <- c("Mean", "Min", "Max", "# of HHs")
> leg.lty.ss <- c(1,2,4,0)
> leg.lwd.ss <- c(2,1,1,0)
> leg.pch.ss <- c(-1,-1,-1,16)
> leg.col.ss <- c("black", "darkolivegreen4", "chartreuse4", "blue")
> }
>
>
> ##*************************************************
> ## Set up vector of possible colors for the lines
> ##*************************************************
> colorset <- c(3:12, 26:62, 67:79, 81, 83:137, 139, 142:151)
>
> ##*************************************************
> ## Set up plotting parameters for the individual
> ## household graph
> ##*************************************************
> ## Create a vector of colors from the colorset
> ## above, one for every HHID00
> colors.id <- sample(colorset, length(uniq.hh.ids), replace=TRUE)
> ## Other parameters
> ttl.hh <- paste("Change in Household Wealth Over Time\n (Village",
> villnum, ")", sep="")
> leg.txt.hh <- c("Old Households", "Split Households")
>
> ##*************************************************
> ## Plot household-level summary statistics
> ##*************************************************
> png(filename=output.png.wlthss, width=10, height=7, units="in", res=300)
>
> ## Set initial plot with mean
> plot(hh.wealth.plot.ss$Year, # x var
> hh.wealth.plot.ss$Mean, # y var (MEAN)
> type="l", # line graph
> xlim=c(0,max.yr), # x-axis limits
> ylim=c(ylim.min, ylim.max), # y-axis limits
> lty=1, # solid line
> lwd=2, # line thickness
> xlab="",
> ylab="Wealth", # y-axis label
> main=ttl.ss)
> ## Add MIN
> lines(hh.wealth.plot.ss$Year, # x var
> hh.wealth.plot.ss$Min, # y var (MIN)
> type="l", # line graph
> col="darkolivegreen4",
> lty=2)
> ## Add MAX
> lines(hh.wealth.plot.ss$Year, # x var
> hh.wealth.plot.ss$Max, # y var (MAX)
> type="l", # line graph
> col="chartreuse4",
> lty=4)
>
> ` ## Add ERROR BARS if Argument 'err.bars' is TRUE
> if (err.bars == TRUE) {
> ## Add LOW ERROR BAR
> lines(hh.wealth.plot.ss$Year, # x var
> hh.wealth.plot.ss$EB.Low, # y var (EB LOW)
> type="l", # line graph
> col="red",
> lty=3)
> ## Add HIGH ERROR BAR
> lines(hh.wealth.plot.ss$Year, # x var
> hh.wealth.plot.ss$EB.High, # y var (EB HIGH)
> type="l", # line graph
> col="red",
> lty=3)
> }
> ## Add QUANTILES if Argument 'n.quantiles' is >= 3
> if (n.quantiles >= 3) {
> # Cycle through column numbers and draw quantile lines
> for (qcol in 1:length(cols.q)) {
> lines(hh.wealth.quantiles$Year, # Plot quantile lines
> hh.wealth.quantiles[,cols.q[qcol]],
> type="l",
> col="orange",
> lty=3)
> }
> # Add MEDIAN line
> if (plot.med == TRUE) {
> lines(hh.wealth.quantiles$Year, # Plot median
> hh.wealth.quantiles[,col.med],
> type="l",
> col="orange",
> lty=3,
> lwd=2)
> }
> }
> ## Add COUNT
> points(hh.wealth.plot.ss$Year, # x var
> hh.wealth.plot.ss$Count, # y var (COUNT)
> type="p", # line graph
> pch=16,
> col="blue",
> cex=0.5)
> ## Add LEGEND
> legend(x="topright",
> leg.txt.ss,
> lty=leg.lty.ss,
> lwd=leg.lwd.ss,
> pch=leg.pch.ss,
> col=leg.col.ss,
> cex=1)
>
> dev.off()
>
>
> ##*************************************************
> ## Plot wealth for individual households
> ##*************************************************
> png(filename=output.png.wlth, width=10, height=7, units="in", res=300)
>
> ## Create an empty plot
> if (log.plot == FALSE) {
> plot(hh.wealth.plot$Year, hh.wealth.plot$Wealth,
> type="n",
> xlim=c(0,max.yr),
> main=ttl.hh,
> xlab="",
> ylab="Wealth")
> } else {
> plot(hh.wealth.plot$Year, hh.wealth.plot$Wealth,
> log="y",
> type="n",
> xlim=c(0,max.yr),
> main=ttl.hh,
> xlab="",
> ylab="Wealth (log scale)")
> }
>
> #legend(x=leg.x.coord, y=leg.y.coord, # Sets the location for the legend
> legend(x="topright",
> leg.txt.hh, # text in the legent
> col=c("red", "red"), # sets the line colors in the legend
> lty=c(1,3), # draws lines
> lwd=c(1,1), # sets line thickness
> # bty="n", # no border on the legend
> ncol=2, # makes it a 2-column legend
> cex=0.8) # sets the legend text size
>
> ## Loop through IDs and add a line for each
> for (id in 1:length(uniq.hh.ids)) {
> ## Get the current HH ID
> this.id <- uniq.hh.ids[id]
>
> ## Extract the records for the current ID
> this.sub <- hh.wealth.plot[hh.wealth.plot$HHID00 == this.id,]
>
> if (dim(this.sub)[1] > 0) {
>
> ## Set line type
> if (mean(this.sub$Status) == 0) {
> ltype <- 1
> } else {
> ltype <- 3
> }
>
> ## Add the line for this ID
> lines(this.sub$Year, this.sub$Wealth,
> type="l",
> col= colors.id[id],
> lwd=1,
> lty=ltype)
> }
>
> }
>
> dev.off()
>
> }
More information about the R-help
mailing list