use lapply and plot to draw multiple plots - r

try to run the following code, but always got error message:
Error in text.default(x, y, txt, cex = cex, font = font) : invalid
mathematical annotation
par(mfrow=c(2,3))
x <- c(1:4,6:9)
myPlot<-function(x){
plot(pros.dat, pros.dat$svi ~ pros.dat[,x])
}
lapply(c(1:4,6:9), FUN=myPlot)
Could anybody tell me what's wrong? Thanks

R's plot function's definition is:
plot(x, y, ...)
So you should define your function as:
myPlot<-function(x){
plot(pros.dat$svi, pros.dat[,x])
}

Related

How can I get albine() to be recognized as a function in Rstudio?

albine(reg=acorn.pl.reg, col="red")
Error in albine(reg = acorn.pl.reg, col = "red") :
could not find function "albine"
This is a syntax error. I think you want to use the function abline and you wrote albine.

how do deparse & substitute work to allow access to an objects name?

My question is regarding the following code:
myfunc <- function(v1) {
deparse(substitute(v1))
}
myfunc(foo)
[1] "foo"
I typed in ?deparse and ?substitute into R and obtained the following:
deparse = Turn unevaluated expressions into character strings.
and
substitute = returns the parse tree for the (unevaluated) expression expr,
substituting any variables bound in env.
I don't seem to really understand this language. Would someone be able to simplify the technical aspect of these descriptions so that I could begin to appreciate how these two functions work together to allow us to do something cool like access the variable name of an object?
I struggle(d) with this too. The myplot() example from ?substitute is helpful. There, they define:
myplot <- function(x, y)
plot(x, y, xlab = deparse(substitute(x)),
ylab = deparse(substitute(y)))
calling
myplot(x=1:10, y = rnorm(10))
gives
whereas the alternative
x = 1:10
y = rnorm(10)
plot(x, y, xlab = x, ylab = y)
gives
Hopefully this shows what deparse(substitute()) is used for. In the plot version, the xlab and ylab arguments are the outputs of whatever was used to generate x and y. myplot knows to pass "character string versions of the actual arguments to the function" for xlab and ylab. (quotes from ?substitute)

Modifying dots (...) inside a function

I'm trying to modify the dots (...) inside a custom function. Here's a simplified example of my plot2 function, which displays a plot onscreen with type="p" (the default) and saves an svg with type="l". The problem surfaces when one of the ... plot options is already in the function. In this example, "type" is matched by multiple actual arguments.
plot2 <-function(...){
plot(...) #visible on screen
svg("c:/temp/out.svg") #saved to file
plot(...,type="l")
dev.off()
}
#This works
plot2(1:10)
#This does not work because type is redefined
plot2(1:10, type="o")
I have tried to put the dots in a list inside the function and modify it, but plot does not accept a list as an input.
#Does not work
plot2 <-function(...){
plot(...)
dots <<-list(...)
print(dots)
if("type" %in% names(dots)) dots$type="l"
print(dots)
svg("c:/temp/out.svg")
plot(dots)
dev.off()
}
plot2(1:10, type="o")
Error in xy.coords(x, y, xlabel, ylabel, log) :
'x' is a list, but does not have components 'x' and 'y'
In cases where you want to forward a modified version of ..., you need to do two things:
Capture the dots
Forward the captured dots via do.call.
This works as follows:
plot2 = function (...) {
# capture:
dots = list(...)
# modify:
dots$type = 'l'
# forward call:
do.call(plot, dots)
}
In general, do.call(f, list(‹…›)) is equivalent to f(‹…›).
For what you want, there is a simpler (and better) way, and you do not need to touch to .... By explicitly defining the arguments that need a special treatment, you take them out of the catch all .... This is also a sane approach that is more explicit about what the function does (in its formal arguments). Here is how to do it:
plot2 <- function(x, type = "p", ...) {
plot(x, type = type, ...) #visible on screen
svg("out.svg") #saved to file
plot(x, ..., type = "l")
dev.off()
}
plot2(1:10)
plot2(1:10, type = "o")

Error using bquote() for axis labelling

I'm experiencing a strange error when using the function bquote for axis labeling. The error is only occurring when applying the label (the greek symbol "mu") to the y-axis:
df <- data.frame(x=1:10, y=1:10)
plot(y~x, df, t="l", xlab=bquote(.("Size [")*mu*m*.("]"))) # works
plot(y~x, df, t="l", ylab=bquote(.("Size [")*mu*m*.("]"))) # doesn't work
# Error in plot.default(1:10, 1:10, ylab = "Size [" * mu * m * "]", xlab = quote("x"), : object 'mu' not found
I know I could use expression as an alternative in this case, but I'm trying to understand the error.
This is due to subtleties of evaluation rules and the specifics of the implementation of this plotting function.
Note that this does not occur when not using the formula interface
plot(df$x,df$y, type="l", ylab=bquote(.("Size [")*mu*m*.("]"))) #works as you expect
To see what is happening, examine the source
getAnywhere("plot.formula")
and you'll see the equivalent of this simplified example
plotex<-function(x,y,type="l",ylab,...) {
m=match.call(expand.dots = FALSE)
dots <- lapply(m$..., eval)
dots$xlab <- enquote(dots$xlab)
do.call(plot,c(list(x=x,y=y,type=type,ylab=ylab),dots))
}
The xlab argument is in ... and protected against evaluation with an explicit enquote. The ylab is a named parameter and its evaluation is forced by inclusion in the list provided to do.call.

Scatter plot best fit line error in R - Error in formula.default(object, env = baseenv())

I am trying to plot a simple best fit line to a scatterplot.
this example works:
plot(dist ~ speed, data= cars, xlab="Speed", ylab="Distance", col= "blue")
title(main="Scatter plot with best-fit line", font.main= 4)
abline(lm(dist ~ speed, data= cars), col= "red")
however with my data I get an error message:
plot(log(datatest$MEAN_intact_for),log(datatest$ERmammal_0_1), col= "blue")
title(main="Scatter plot with best-fit line", font.main= 4)
abline(lm(log(datatest$ERmammal_0_1)~log(datatest$MEAN_intact_for)), col= "red")
Error in lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
NA/NaN/Inf in 'x'
I have tried searching it but I am new to R and so if anyone can give me any simple advice on this that would be great.
- when I just plot the graph it works fine, the problem is when I add the abline command to get a best fit line.
I also tried
Hopefully someone can help. Apologies if its really obvious.
When you use abline() you need to input the intercept (a) and slope (b) as parameters, rather than just sticking the lm() in there. So let's say:
fmla = lm(log(datatest$ERmammal_0_1)~log(datatest$MEAN_intact_for))
then you want:
abline(a = fmla$coefficients[1], b = fmla$coefficients[2])

Resources