I am trying to write a function with a graph-output.
I would like to insert a legend with a value of the argument.
For example:
f<-function(x,alpha=0.9){
....
plot(x)
legend("topleft",expression(alpha)???)
}
'expression(alpha)' should equal the current value of alpha.
Can anyone tell me how I can do it?
I don't see a test case yet, but the usual answer to this sort of question (where one portion of an expression needs to be evaluated) is bquote with its built-in .() function:
f<-function(x,alpha=0.9){ .... plot(x) legend("topleft", bquote(.(alpha)) ) }
The `.() function isolates the section(s) that deserve evaluation. See also the plotmath page:
?plotmath
Sometimes substitute is needed:
alpha=0.2
substitute( alpha, list(alpha=alpha) )
#0.2
.... but most people find bquote easier to work with.
The addtional code requested with some editing to avoid overwriting label1:
x<-seq(0,60,length=150)
y<-rnorm(150,0,10)
yy<-x+y
d<-cbind(x,yy)
m<-lm(d[,2]~d[,1])
plot(x,yy) > abline(m)
label1<-summary(m)$'r.squared'
label2<-summary(m)$'adj.r.squared'
legend("topleft", legend=bquote( R^2==.(label1)*";"~Adj.R^2==.(label2) ) )
Related
I trying to plot vectors of electric field in scilab. But it always error :
champ: Wrong size for input arguments: Incompatible sizes.
the code:
epsilon0=1e-9/(36*%pi);
q=3e-9;
p=[-1,0,0];
x=-2:0.2:2;
y=-2:0.2:2;
[px,py]=meshgrid(x,y);
for m=1:length(x),
for n=1:length(y),
xp=px(m,n);
yp=py(m,n);
vektorr1x=xp-p(1);
vektorr1y=yp-p(3);
r1=sqrt(vektorr1x^2+vektorr1z^2);
if r1~=0 then
ar1x=vektorr1x/r1;
ar1y=vektorr1y/r1;
E1x=q*ar1x/(4*%pi*epsilon0*r1^2);
E1y=q*ar1y/(4*%pi*epsilon0*r1^2);
else
E1x=0;
E1y=0;
end,
end,
end,
pl=champ(px,py,E1x,E1y,[-2,-1,2,-1]);
You don't have to use loops, the following script does what you want:
epsilon0=1e-9/(36*%pi);
q=3e-9;
p=[-1,0,0];
x=-2:0.2:2;
y=-2:0.2:2;
[px,py]=ndgrid(x,y);
vektorr1x=px-p(1);
vektorr1y=py-p(3);
r1=sqrt(vektorr1x.^2+vektorr1y.^2);
ar1x=vektorr1x./r1;
ar1y=vektorr1y./r1;
E1x=q*ar1x./(4*%pi*epsilon0*r1.^2);
E1y=q*ar1y./(4*%pi*epsilon0*r1.^2);
E1x(r1==0)=0;
E1y(r1==0)=0;
clf
champ(x,y,E1x,E1y,[-2,-1,2,-1]);
To plot fields don't use meshgrid to sample the domain use ngrid instead. Moreover, don't forget to use dot-prefixed operators.
My code is written in a file "plot.m".
If I put the following code in "plot.m", when I call plot("20%"), the Octave GUI will keep opening a new window with a new figure indefinitely.
function X = plot(folderName)
X = 0;
data = ([folderName, "\\summary.txt"]);
NUM_SURVIVED = data(1);
NUM_DATA = size(data)(1)-1;
FINAL_WEALTH = data(2 : NUM_DATA);
%plot FINAL_WEALTH
figure;
plot(1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2);
xlabel('x');
ylabel('FINAL_WEALTH');
end
However, if I put the following code in "plot.m" and run it, the program works as intended and will plot data from "summary.txt".
data = ("20%\\summary.txt");
NUM_SURVIVED = data(1);
NUM_DATA = size(data)(1)-1;
FINAL_WEALTH = data(2 : NUM_DATA);
%plot FINAL_WEALTH
figure;
plot(1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2);
xlabel('x');
ylabel('FINAL_WEALTH');
Any idea what I am doing wrong in the first section of code? I would like to write it as a function so that I can call it multiple times for different folder names.
When you call plot from the function plot, you get endless recursion. Rename your function and its file.
Just adding to Michael's answer, if you really wanted to name your function as "plot" and override the built-in plot function, but still wanted to be able to call the built-in plot function inside it, this is actually possible to do by using the builtin function to call the built-in version of plot. Your code would then look like this:
function X = plot (folderName)
% same code as before
figure;
builtin ("plot", 1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2);
xlabel ('x');
ylabel ('FINAL_WEALTH');
end
Obviously, whether it's a good idea to overload such a core function in the first place is an entirely different discussion topic. (Hint: don't!)
here i am giving the code
#my user defined function
my.display<-function(x,display=TRUE,type="hist",prob=TRUE)
{
if(display=TRUE)
print("1")
else hist(x)
if(type=hist) hist(x) elseif(type=density) plot(density(x))
cat("Please specify type as either hist or density")
if(prob=TRUE) hist(x,freq=TRUE) else hist(x,freq=TRUE)
}
the error r shows is when it passes to the if(display=TRUE), I believe the expression is wrong or something. if the display=TRUE argument then it should print 1 else generate a histogram of the vector x.
if(type=hist) also showing error . someone please help.
= acts as assign operator same as <- operator in R
while == is a logical operator.
So you should use if(display == TRUE). You might also want to add some {} in your if-else structures for readability.
Try this code for second doubt
updated:
my.display<-function(x,display,type,prob=TRUE)
{if(display==TRUE){
print("1")
}
else
if(type=="hist") {hist(x)}
else
if(type=="density") {plot(density(x))}
else
cat("Please specify type as either hist or density")
if(prob==TRUE){ hist(x,freq=TRUE)}
else
hist(x,freq=TRUE)
}
I am trying to create a function which will look at two vectors of character labels, and print the appropriate label based on an If statement. I am running into an issue when one of the vectors is populated by NA.
I'll truncate my function:
eventTypepriority=function(a,b) {
if(is.na(a)) {print(b)}
if(is.na(b)) {print(a)}
if(a=="BW"& b=="BW",) {print("BW")}
if(a=="?BW"& b=="BW") {print("?BW")}
...#and so on
}
Some data:
a=c("Pm", "BW", "?BW")
b=c("PmDP","?BW",NA)
c=mapply(eventTypepriority, a,b, USE.NAMES = TRUE)
The function works fine for the first two, selecting the label I've designated in my if statements. However, when it gets to the third pair I receive this error:
Error in if (a == "?BW" & b == "BW") { :
missing value where TRUE/FALSE needed
I'm guessing this is because at that place, b=NA, and this is the first if statement, outside of the 'is.na' statements, that need it to ignore missing values.
Is there a way to handle this? I'd really rather not add conditional statements for every label and NA. I've also tried:
-is.null (same error message)
-Regular Expressions:
if(a==grepl([:print:]) & b==NA) {print(a)}
In various formats, including if(a==grepl(:print:)... No avail. I receive an 'Error: unexpected '[' or whatever character R didn't like first to tell me this is wrong.
All comments and thoughts would be appreciated. ^_^
if all your if conditions are exclusives, just call return() to avoid checking other conditions when one is met:
eventTypepriority=function(a,b) {
if(is.na(a)) {print(b);return()}
if(is.na(b)) {print(a);return()}
if(a=="BW"& b=="BW",) {print("BW");return()}
if(a=="?BW"& b=="BW") {print("?BW");return()}
...#and so on
}
You need to use if .. else statements instead of simply if; otherwise, your function will evaluate the 3rd and 4th lines even when one of the values is n/a.
Given you mapply statement, I also assume you want the function to output the corresponding label, not just print it?
In that case
eventTypepriority<-function(a,b) {
if(is.na(a)) b
else if(is.na(b)) a
else if(a=="BW"& b=="BW") "BW"
else if(a=="?BW"& b=="BW") "?BW"
else "..."
}
a=c("Pm", "BW", "?BW")
b=c("PmDP","?BW",NA)
c=mapply(eventTypepriority, a,b, USE.NAMES = T)
c
returns
Pm BW ?BW
"..." "..." "?BW"
If you actually want to just print the label and have your function return something else, you should be able to figure it out from here.
I hope this is not a double post. I've been looking for an answer.
I have a function that returns a rather big list. So i would like it to print some text in between all the results of the list. A bit as you know it from lm and other models.
Consider this R script
y<-function(z)
{
l<-list()
print("hello world")
l$answer<-2*z
return(l)
}
x<-y(5)
This is a small example. I tried a solution with print but this is a bad solution , simply because it executes print when i save the variable as x<-fun(5). I just want it to execute text when you ask it explicit, or even better,if you can construct your own "summary" command to a list.
Thanks for your time.
If I understood what you want to do , I think you are looking to implement the S3method print.
set the class attribute :"someclass" of the y function return value
define print.someclass
here the code:
y<-function(z)
{
l<-list()
l$answer<-2*z
## Roland comment : usually better to preserve existing classes:
class(l) <- c('someclass', class(l))
return(l)
}
print.someclass<-
function(x,...){ ## add here what you want to print
print("hello world")
}
x<-y(5)
Now when you type x at console or print(x):
x
[1] "hello world"