here is the problem. I have two lists of vectors, sorted (i hope, but i thing i can sort them if they arent) where ith vector in first list has as many numbers as ith vector in the second list. I just want to plot them. But I fear R cant plot elements of lists. Any ideas how to fix that? Thx a lot. Here is the code i tried.
a<-c(2,1,5)
b<-c(2,2,2)
f<-c(4)
g<-c(1)
k<-list(a,f)
l<-list(b,g)
for(i in 1:2){
plot(l[i],k[i])}
and the issue is
Error in xy.coords(x, y, xlabel, ylabel, log) :
(list) object cannot be coerced to type 'double'
The best way to do it is to avoid the for-loop and unlist the lists in order to plot them.
This is a way using unlist:
plot(unlist(l),unlist(k))
The way to do it with a for-loop would be the following:
for (i in 1:2) {
par(new=T)
plot(l[[i]], k[[i]], xlim=c(0,2), ylim=c(0,5))
}
But it is totally unnecessary as you can get the same result simply by unlisting. You would also have to use par(new=T) so that the second (or any other) plot won't overwrite the previous ones and you would have to specify x and y limits so that the two plots would have the same scales. Also, you would have to use double square brackets [[]] as #HubertL mentions in his answer to access the lists. The result would be the same as above (with the labels in a bolder format since labels would be plotted twice on top of each other).
You can try to use double brackets[[]]:
plot(l[[i]],k[[i]])
Almost there, as #HubertL, just two brackets
a<-c(2,1,5)
b<-c(2,2,2)
f<-c(4)
g<-c(1)
k<-list(a,f)
l<-list(b,g)
for(i in 1:2){
plot(l[[i]],k[[i]])
}
Related
I always desire to have my R code as flexible as possible; at present I have three (potentially more) curves to compare based on a parameter delta, but I don't want to hardcode the values of delta anywhere (or even how many values if I can avoid it).
I am trying to make a legend that involves both Greek and a variable substitution for the delta values, so each legend entry is of the form like 'delta = 0.01', where delta is Greek and 0.01 is determined by variable. Many different combinations of paste, substitute, bquote and expression have been tried, but always end up with some verbatim code leftover in the finished legend, OR fail to put 'delta' into symbolic form.
delta <- c(0.01,0.05,0.1)
plot(type="n", x=1:5, y=1:5) #the curves themselves are irrelevant
legend_text <- vector(length=length(delta)) #I don't think lists work either
for(i in 1:length(delta)){
legend_text[i] <- substitute(paste(delta,"=",D),list(D=delta[i]) )
}
legend(x="topleft", fill=rainbow(length(delta)), legend=legend_text)
Since legend=substitute(paste(delta,"=",D),list(D=delta[1]) works for a single entry, I've also tried doing a 'semi-hardcoded' version, fixing the length of delta:
legend(x="topleft", fill=rainbow(length(delta)),
legend=c(substitute(paste(delta,"=",A), list(A=delta[1])),
substitute(paste(delta,"=",B), list(B=delta[2])),
substitute(paste(delta,"=",C), list(C=delta[3])) )
)
but this has the same issues as before.
Is there a way I can do this, or do I need to change the code by hand with each update of delta?
Try using lapply() with as.expression() to generate your legend labels. Also use bquote to create your individual expressions
legend_text <- as.expression(lapply(delta, function(d) {
bquote(delta==.(d))
} ))
Note that with plotmath you need == to get an equals sign. Also no need for paste() since nothing is really a string here.
I am attempting to create a simple barplot with both negative and positive values with my input as a vector. I would like the barplot to display the positive values colored in red and the negative values colored in blue. I understand this problem is simple, but I cannot seem to figure it out.
Here is my vector:
x <- (1.9230769, 1.2961538, 0.2576923, -1.5500000, -1.3192308,
0.2192308, 1.8346154, 1.6038462, 2.5653846, 4.1423077)
I have attempted the code:
barplot(x, ylim=c(-8,8), if(x>0) {col="red"} else {col="blue"})
but I keep getting an error that says
"In if (x > 0) { : the condition has length > 1 and only the first
element will be used"
How can I get it to understand to run through the entire vector and plot it conditionally with red and blue?
Thanks,
Adam
Use
barplot(x, ylim=c(-8,8), col=ifelse(x>0,"red","blue"))
col= expects a vector with the same length as x (or it will recycle values). And you can't really conditionally specify parameters like that. The ifelse will make the vector as desired unlike if which only runs once.
I want to create a series of x-y scatter charts, where y is always the same variable and x are the variables I want to check if they are correlated with. As an example lets use the mtcars dataset.
I am relatively new to R but getting better.
The code below works, the list charts contains all the charts, except that the X axis shows as "x", and I want it to be the name of the variable. I tried numerous combinations of xlab= and I do not seem to get it
if I use names(data) I see the names I want to use. I guess I want to reference the first of names(data) the first iteration of apply, the second the second time, etc. How can I do that?
Th next step would be to print them in a lattice together, I assume an lapply or sapply will do the trick with the print function - I appreciate idea for this too, just pointers I do not need a solution.
load(mtcars)
mypanel <- function(x,y,...) {
panel.xyplot(x,data[,y],...)
panel.grid(x=-1,y=-1)
panel.lmline(x,y,col="red",lwd=1,lty=1)
}
data <- mtcars[,2:11]
charts <- apply(data,2,function(x) xyplot (mtcars[,1] ~ x, panel=mypanel,ylab="MPG"))
This all started because I was not able to use the panel function to cycle.
I did not find that this code "worked". Modified it to do so:
mypanel <- function(x,y,...) {
panel.xyplot(x, y, ...)
panel.grid(x=-1, y=-1)
panel.lmline(x,y,col="red",lwd=1,lty=1)
}
data <- mtcars[,2:11]
charts <- lapply(names(data), function(x) { xyplot (mtcars[,1] ~ mtcars[,x],
panel=mypanel,ylab="MPG", xlab=x)})
Needed to remove the 'data[,y]' from the panel function and pass names instead of column vectors so there was something to use for a x-label.
Yesterday, I asked a question regarding how to plot multiple (horizontal-ish) lines, each with a user-specified color, without using a loop.
I tried to use the suggested function matplot() to plot the short vertical lines shown in the plot below with the relevant code.
ci = matrix(1:30, nrow=3, byrow=T)
ci=list(rbind(ci[1,], ci[1,]+2),
rbind(ci[2,], ci[2,]+2),
rbind(ci[3,], ci[3,]+2))
x = rbind(1:10, 1:10)
plot(-5, xlim=c(1,10), ylim=c(1,32))
invisible(mapply(matlines, x=list(x), y=ci,
col=c("red","blue","black"),
lty = 1))
This is all good. However, I am trying to wrap this code inside a function, and I would like to be able to input a list of optional arguments, which can then be passed to mapply/matlines. I tried to use the argument MoreArgs in mapply() to no avail. It seems that arguments that MoreArgs takes are not treated the same as others. As you can see in the first code, each item of the list gets a different color, but when I put col inside the list args.ci, the 3 colors are recycled within each item of the list. I wonder if there is anyway to resolve this issue so that if I have multiple values for an argument, each value gets applied to one item of a list. Thanks!
args.ci = list(col=c("red","blue","black"), lty=1:3)
plot(-5, xlim=c(1,10), ylim=c(1,32))
invisible(mapply(matlines, x=list(x), y=ci,
MoreArgs = args.ci))
Here's a general approach to this sort of problem. You should be able to adapt it to do more exactly what you want:
myFun <- function(...) {
fixedArgs <- list(matlines, x=list(x), y=ci)
dots <- list(...)
allArgs <- c(fixedArgs, dots)
plot(-5, xlim=c(1,10), ylim=c(1,32))
invisible(do.call(mapply, allArgs))
}
myFun(col=c("red","blue","black"), lty=1)
I am trying to use the plot function in R. I would like to have the values which are represented on the X-axis to be on the Y-axis and vice-versa.
Another question I have is I have a list of dates with me. I want to know how many instances of a particular date are there in the list.
How should I go about doing this ?
1)
plot(y, x) # I'm guessing there is something you are not telling us.
In the situation where you are using the default indexing with a single "y" vector the answer would be:
plot( x=y, y= 1:length(y) )
# This was reversed when it was posted as an edit-response to the comment.
2)
table(dates)[as.Date("YYYY-MM-DD")] # with the obvious substitutions