0

I am new to R and have been trying to figure this out for a while. Basically, I have a data frame, and various y variables. I am trying to write a function that will allow me to come up with a customized graph template for the many different y variables that I have. I am trying the following code below but I am met with this error:

1: In eval(expr, envir, enclos) : NAs introduced by coercion

2: In aes_string(xvar[max(which(complete.cases(yvar)))], yvar[max(which(complete.cases(yvar)))], : NAs introduced by coercion

The code works if I add the variables in directly and not through a function. I believe that it is something to do with how the function plugs in the xvar into the as.numeric() function. I am not sure but any of you knows how to deal with this?

test <- function (Data, xvar, yvar){
  # Plot data
  plot <- ggplot(subset(Data,!is.na((yvar))), aes_string(xvar, yvar)) + geom_line(colour="darkblue") + theme_bw()
  # Add Trendline for recent data
  plot <- plot + geom_smooth(data=subset(Data, xvar > as.numeric(xvar)[max(which(complete.cases(yvar)))-8]), method = "lm")
  # Label most recent data
  plot + geom_text(data = Data, aes_string(xvar[max(which(complete.cases(yvar)))],
                             yvar[max(which(complete.cases(yvar)))],
                             label = as.numeric(yvar)[max(which(complete.cases(yvar)))],
                             hjust= -0.5, vjust = 0.5))
2
  • aes_string expects a character string. xvar[max(which(complete.cases(yvar))) doesn't make sense there. Compute this outside of ggplot2. Also, do not use subset inside functions. It's documentation warns against this. Commented May 31, 2016 at 9:05
  • Thanks a lot! I see what you mean! Commented May 31, 2016 at 9:31

2 Answers 2

1

As xvar is probably (you do not show a reproducible example) a character vector of length 1, subsetting like xvar[] will not yield the desired result.

You could try something like

library(ggplot2)
f <- function(data, xvar, yvar) {
  ggplot(data, aes_string(xvar, yvar)) + 
    geom_point() + 
    geom_smooth(data=subset(data, eval(parse(text=xvar)) > 5), method = "lm")
}

or

f <- function(data, xvar, yvar) {
  ggplot(data, aes_string(xvar, yvar)) + 
    geom_point() + 
    geom_smooth(data = data[data[, xvar]>5, ], method = "lm")
}

f(mtcars, "cyl", "disp")
Sign up to request clarification or add additional context in comments.

1 Comment

I still don't get how it can be corrected? I understand that it's a character vector of length 1 (is this the same as a character string?). Assuming I have a data of such initially: > X1 <- as.yearqtr(seq(as.Date("2010/3/1"), by = "quarter", length.out = 10)) > Y1 <- as.vector(c(124,315,363,574,345,434,141,512,142,647)) > Data1 <- data.frame(X1, Y1)
0

I think @LukeA has gotten you practically all the way there, but here is an example that uses your data and adds a few more columns to help demonstrate how you can pass column names into ggplot inside your own function.

It uses your variable names. It subsets your data into a data.frame with non-missing values for y, and then it subsets your data into a separate data.frame that allows you to add additional filtering criteria to your smoothing function.

library(zoo)
set.seed(72)

X1 <- as.yearqtr(seq(as.Date("2010/3/1"), by = "quarter", length.out = 10))
Y1 <- as.vector(c(124,315,363,574,345,434,141,512,142,647))
Y2 <- sample(Y1)
Y3 <- sample(Y1)

Data1 <- data.frame(X1, Y1, Y2, Y3) 


plot_function <- function(data, xvar, yvar){

  # remove rows with NA on yvar
  mydata1 <- data[!is.na(data[, yvar]), ]

  # remove rows with NA on yvar and subset yvar above some threshold
  mydata2 <- data[!is.na(data[, yvar]) & data[, yvar] > 400, ]

  # plot it
  myplot <- ggplot(mydata1, aes_string(xvar, yvar)) + 
    geom_line(colour="darkblue") + 
    scale_x_yearqtr(limits = c(min(mydata1[, xvar]), max(mydata1[, xvar])), format = "%YQ%q") +
    geom_smooth(data = mydata2, aes_string(xvar, yvar), method = "lm") +
    geom_text(data = mydata1, aes_string(xvar, yvar, label = yvar),  hjust= -0.5, vjust = 0.5) +
    theme_bw()

  return(myplot)
}


plot_function(data = Data1, xvar = "X1", yvar = "Y1")
plot_function(data = Data1, xvar = "X1", yvar = "Y2")
plot_function(data = Data1, xvar = "X1", yvar = "Y3")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.