1

my code runs well and plots the graphs, when i ran in the consol. however, when i put it in a function, i get an error message indicating that one of the columns could not be found.

"Error in tapply(X = X, INDEX = x, FUN = FUN, ...) :   
object 'm.raw' not found"

first, the data frame i am using for my plot is exactly as below

DF =
lbls    raw.1   raw.2   raw.3   m.raw   imp.1   imp.2   imp.3   m.imp
A1  0.020   0.031   0.032   0.028   11.266  17.408  17.622  15.432
A2  0.023   0.024   0.036   0.028   12.732  13.452  20.034  15.406
A3  0.002   0.022   0.016   0.013   1.344   12.111  9.011   7.489
A4  0.015   0.031   0.021   0.023   8.641   17.575  11.790  12.669
A5  0.016   0.046   0.066   0.043   8.764   25.728  36.991  23.828
A7  0.009   0.029   0.029   0.022   4.924   16.348  16.364  12.545
A7  0.014   0.025   0.029   0.023   7.806   13.747  16.341  12.631

second, when i ran the code below in the console (replacing the x and y) with actual variable names (x = lbls; y = m.raw), i get the plots without any error message.
however, when i put the code in a function (replacing the real variable names with x and y) i get an error message indicated above

# function to plot
dot.pa <- function(mydata, x, y) {
  pa <-  ggplot(data = mydata, (aes(x = reorder(x, y), y))) +
    geom_point() +
    labs(x = "predicts", y = "weights") +
    coord_flip()

  geom.text.size = 10
  theme.size = (10*1.25) # geom.text.size

  pa2 <- pa + theme_minimal() +
    geom_segment(aes(yend=0.00, xend = x)) +
    geom_text(aes(y, label = round(y, 3), 
              family = "mono", size = geom.text.size,
              vjust = -0.5, hjust = 0.9))

  pa3 <- pa2 + 
           theme(text = element_text(family = "mono", size = theme.size), 
                 axis.text.x = element_text(size = theme.size, family = "mono"),
                 axis.text.y = element_text(size = theme.size, family = "mono")) +
           theme(legend.position = "none")
  return(pa3)
}

#plot function
dot.pa(DF, x=lbls, y=m.raw)
camille
  • 16,432
  • 18
  • 38
  • 60
GSA
  • 751
  • 8
  • 12
  • If you call the function with `dot.pa(DF, x=lbls, y=m.raw)` _without quoting the variable names_, then `R` will expect these to exist as objects in the environment. If you pass them as character strings (`dot.pa(DF, x="lbls", y="m.raw")`, then you'd need to convert them to `names` inside the function. – teofil Sep 20 '19 at 20:49
  • Possible duplicate of [pass function arguments to both dplyr and ggplot](https://stackoverflow.com/questions/45439813/pass-function-arguments-to-both-dplyr-and-ggplot) – camille Sep 21 '19 at 02:41
  • You need to do tidyeval to refer to column names. Aside from that directly, one thing that helps with debugging is to keep your code minimal. See the *minimal* part of [mcve]. The actual focus of your question is only a few lines within the function; the rest is making the chart look nice, including assigning charts to 3 different variables, all of which muddies the actual issue – camille Sep 21 '19 at 02:45

2 Answers2

1

A simpler function to show the problem:

make_plot <- function(mydata, x, y) {
  ggplot(mydata, aes(x=x, y=y)) + geom_point()
}

Calling with unquoted names. R expect Species to exist as object in the environment:

make_plot(iris, Species, Sepal.Width)
Error in FUN(X[[i]], ...) : object 'Species' not found

Calling with character strings does not throw an error, but also wouldn't work as we might expect, because ggplot expect unquoted variables within aes:

make_plot(iris, "Species", "Sepal.Width")

enter image description here

Calling with the actual vectors you want to plot works:

make_plot(iris, iris$Species, iris$Sepal.Width)

enter image description here

To call with character strings, but get the expected output, we need to convert to name and then use !!:

make_plot2 <- function(mydata, x, y) {
  ggplot(mydata, aes(x=!!as.name(x), y=!!as.name(y))) + geom_point()
}

make_plot2(iris, "Species", "Sepal.Length")

enter image description here

teofil
  • 2,344
  • 1
  • 8
  • 17
1

with teofil's answer, and reading a bit more about quasiquotations, i was able to get a solution. below is a snippet of the code changes

dot.pa <- function(mydata, x, y) {

x <- enquo(x)
y <- enquo(y)

pa <-  ggplot(data = mydata, (aes(x = reorder(!!x, !!y), !!y))) +
geom_point() + 
labs(x = "predicts", y = "weights") + 
coord_flip()


return(pa)
}

i enquo'ed x and y, then unquoted all instances of !!x and !!y in the function to get it to work without any errors.

GSA
  • 751
  • 8
  • 12