简体   繁体   中英

Apply column names to legend in a function

I'm writing a function that takes two variables -- ideally columns from the same data frame -- and plots them. The plot will also include a legend using the names from the columns, and that's where I'm running into difficulty.

The code below is as close to the desired outcome as I can get. I'm only interested in using base R.

plotpairs <- function(x,y){
  plot(x, type = "l", col = "red")
  lines(y, type = "l", col = "blue")
  legend(0,ylim_max, legend = paste0(x, y), lwd = c(5,5), col = c("red", "blue"), bty = "n")
}

plotpairs(df$F3, df$F4)

在此处输入图片说明

If you supply a data.frame or matrix as argument, you can extract the column names using colnames() , else you have to use deparse(substitute()) , or match.call() as I've used here.

set.seed(1)
F3 <- cumsum(runif(1e3, -2, 2))+runif(1e3)
F4 <- cumsum(rnorm(1e3))+rnorm(1e3, 0, 0.5)
df <- data.frame(F3, F4)

plotpairs <- function(x, y) {
    if (NCOL(x) > 1) {
        nam <- colnames(x)[1:2]
        y <- x[,2]
        x <- x[,1]
    } else {
        nam <- as.character(match.call()[c("x", "y")])
    }
    plot(x, type="l", col="red", ylim=range(c(x, y)))
    lines(y, type="l", col="blue")
    legend("topleft", legend=nam, lwd=c(5, 5), col=c("red", "blue"), bty="n")

}
plotpairs(F3, F4)
with(df, plotpairs(F3, F4)) # same
plotpairs(df)               # same

在此处输入图片说明

This plots the indicated columns from the data frame given as first argument or if no names are given then it plots the first two columns. Note that we first plot both together using type = "n" to ensure that the plot gets set up large enough to accommodate both variables. The example uses the builtin data frame trees .

plotpairs <- function(data, name1 = names(data)[1], name2 = names(data)[2]) {
  both <- c(data[[name1]], data[[name2]])
  plot(seq_along(both) / 2, both, type = "n", xlab = "", ylab = "")
  lines(data[[name1]], type = "l", col = "red")
  lines(data[[name2]], type = "l", col = "blue")
  legend("topleft", legend = c(name1, name2), lwd = 5, 
    col = c("red", "blue"), bty = "n")
}

plotpairs(trees, "Girth", "Volume")

屏幕截图

I also worked out an answer based on the comment @Rui Barradas that included regex. Since I'll be using inputs like "df$F3", I can count on the "$" symbol to be present, though this might limit the flexibility of the code.

plotpairs <- function(x,y){
xnam <- deparse(substitute(x))
ynam <- deparse(substitute(y))
xnam1 <- substring(xnam, regexpr("[$]", xnam)+1)
ynam1 <- substring(ynam, regexpr("[$]", ynam)+1)
plot(x, type = "l", col = "red")
lines(y, type = "l", col = "blue")
legend("topleft", legend = c(paste0(xnam1), paste0(ynam1)),lwd = c(5,5), col = c("red", "blue"), bty = "n")
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM