Connor Brown Connor Brown - 15 days ago 6
R Question

Gel analysis - Plotting ladder returns NULL, cannot edit past this

I am new to programming in R and have hit a stumbling block in my code. I am analysing gels (SDS-PAGE, Western blots etc.) and would like to use a prompt system where the user can enter the measurements made to determine the size (bp, kDa) or their sample.

When plotting the linear line of the ladder, the plot appears but the code returns NULL, which means I can't edit the plot any further.

Here is my code, including the original functions for the prompt:

Sizeladder <- function(){
sl <- readline(prompt="Enter size of bands of ladder, in ascending order: ")
return(as.numeric(unlist(strsplit(sl, split = ","))))
}

Ladderdistance <- function(){
ld <- readline(prompt = "Enter distance each band of the ladder has travelled, bottom to top: ")
return(as.numeric(unlist(strsplit(ld, split = ","))))
}

Samplesize3 <- function(){
Logladder <- plot(log10(Sizeladder()) ~ Ladderdistance())
return(Logladder)
}


I would like to go on to add a linear model line, my sample values and get a returned value but I cannot seem to get past this stage.

Any thoughts?

Answer

Perhaps you can just retrieve the data before your call to plot, ala:

Samplesize3 <- function() {
  x <- Ladderdistance()
  y <- Sizeladder()
  dat <- data.frame(size = x, ladder = y)
  plot(log10(ladder) ~ size, data = dat)
  return(dat)
}

It isn't strictly required to store it in a data.frame; you can call plot(x, log10(y)) directly, but keeping things organized in a data.frame may be preferred. You may want to include some sanity-checks, such as having the same amount of data in each as well as positive-only non-zero ladder values.

Another thought to encourage good user-interaction: allow them to do the data-creation in some spreadsheet program (e.g., Excel, Calc) and copy the data using the clipboard, with something like: highlight the table in Excel, copy it (e.g., Ctrl-c), then run your function which can include:

dat <- read.delim(text = paste(readClipboard(), collapse = "\r\n"), 
                  as.is = TRUE, header = TRUE, ...)

Perhaps having the data saved to a CSV file would also be good, in which case you can call read.csv directly. Here's a slightly-more featureful function:

Samplesize3 <- function(fname, header = TRUE) {
  if (missing(fname)) {
    x <- Ladderdistance()
    y <- Sizeladder()
    dat <- data.frame(size = x, ladder = y)
  } else if (fname == "clipboard") {
    dat <- read.delim(text = paste(readClipboard(), collapse = "\r\n"), 
                      as.is = TRUE, header = TRUE)
  } else {
    fileext <- tolower(gsub(".*\\.", "", fname))
    if (fileext == "csv") {
      dat <- read.csv(fname, header = header, as.is = TRUE)
    } else {
      stop("unknown file format: ", sQuote(fileext))
    }
  }
  # assuming two columns!
  if (! header && ! missing(fname)) colnames(dat) <- c("ladder", "size")
  # quick sanity-check for names, relevant if fname/clipboard used
  if (! all(c("ladder", "size") %in% colnames(dat))) {
    stop("the data needs to have at least two columns, named 'ladder' and 'size'")
  }
  plot(log10(ladder) ~ size, data = dat)
  return(dat)
}

If the user calls it with no argument, it prompts them (as you initially have in your function). If they use Samplesize3("clipboard") then it will assume that they have already highlighted and copied the table elsewhere, and that the column names are correct (header=TRUE, the default) or only two columns are provided and assigned. If they use Samplesize3("somefile.csv"), then the same column assumptions are made but the data is read directly from a saved file.