enter image description here
I know there exists function 'unique' which works similar to what I want to make, but I want to make this function.
I want this function finally returns 'result' which contains unique elements of input vector.
But I don't know why this function's result is totally different from my expect.
Why c which is to combine before result and new unique element is not working.
Please tell me how to fix my code.
Thank you.
I think what you expect might be something like below, where result should be an argument of m_uni:
m_uni <- function(x,result = c()) {
if (class(x)=='numeric'| class(x)=='character') {
if (length(x) <= 1){
return(result)
} else {
if (x[length(x)] %in% result) {
x <- x[-length(x)]
m_uni(x,result)
} else {
result <- c(result,x[length(x)])
x <- x[-length(x)]
m_uni(x,result)
}
}
} else {
return('This function only gets numeric or character vector')
}
}
such that
> m_uni(x)
[1] 0 4 5 -2
I am trying to create a condition for an if-loop which is not predefined. The "length" of the condition is depending of the length of my List
where prior calculated values are stored.
The proceed you can see in my code down below.
I tried to convert my character condition with some functions (expression(), eval() ...) so that the condition is readable for the if loop. But nothing works...
So I hope you can help me solving my issue.
My Code:
# the list with prior calculated values
List=list(0.96,0.89,0.78)
# rendering the condition
condition=character()
for (m in 1:length(List)) {
if (m==length(List)) {
condition=paste0(condition,"List[[",m,"]]>=0.6")
} else {
condition=paste0(condition,"List[[",m,"]]>=0.6 && ")
} # end if-loop
} # end for-loop
# to see what the condition looks like
print(condition)
# the just rendered condition in the if loop
if(condition) {
print("do this ...")
} else {
print("do that ...")
} # end if-loop
You need to parse the text when you use eval:
eval(parse(text=condition))
This returns TRUE in your example, so you can use it as follows:
if(eval(parse(text=condition))) {
print("do this ...")
} else {
print("do that ...")
} # end if-loop
Output:
[1] "do this ..."
You can find more information about eval here: Evaluate expression given as a string
So I'm trying to do a recursive calculation with time-steps h, and the time is t.
I want the second if-function (in the while-loop) to check if the time t is an integer. It works for the first loop when t=9, but after that it ignores when t=8,7,6,... and so on. And right now I just don't understand why.
I would be very grateful for any help or ideas!
h=1/12;
b1=10000;
b2=25000*0.15*12; #45000
mu_10=0.004183;
mu_12=0.002136;
mu_20=0.0050196;
mu_21=0.005;
V1_start=h*(-b1);
V2_start=h*(b2);
t_vektor<-c(10);
V1_vektor<-c(V1_start);
V2_vektor<-c(V2_start);
t=as.integer(9);
while (t>0){
if(t==1){
V1_ny=V1_start+h*(-log(1.04)*V1_start+b1-mu_10*V1_start+mu_12*(V2_start-V1_start));
}else{
V1_ny=V1_start+h*(-log(1.04)*V1_start-mu_10*V1_start+mu_12*(V2_start-V1_start));
}
V2_ny=V2_start+h*(-log(1.04)*V2_start+b2-mu_20*V2_start+mu_21*(V1_start-V2_start));
if(round(t)==t){
V1_vektor<-c(V1_vektor,V1_ny);
V2_vektor<-c(V2_vektor,V2_ny);
t_vektor<-c(t_vektor,t);
V2_start=V2_ny;
V1_start=V1_ny;
t=t-h;
}else{
V2_start=V2_ny;
V1_start=V1_ny;
t=t-h;
print(t)
}
}
This has to do with the way numbers are stored, see also here.
An example for your case, see the output of the following code:
t = 9
h=1/12
for(i in 1:12)
{
t=t-h
}
print(t) # 8
print(t==8) # FALSE
all.equal(t,8) # TRUE
in your case, try:
isTRUE(all.equal(round(t),t))
Hope this helps!
Instead of if(round(t)==t) use:
tolerance = h/2;
if(min(abs(c(t%%1, t%%1-1))) < tolerance){
...
}
You make your test on t, but you change t before printing it by the line "t=t-h";
So you don't see the value witch was tested ..
I am trying to cut down a list of gene names that I have been given. I'm trying to eliminate any repetitive names that may be present but I keep getting an error when running my code:
counter=0
i=0
j=0
geneNamesRevised=array(dim=length(geneNames))
for (i in 0:length(geneNamesRevised))
geneNamesRevised[i]=""
geneNamesRevised
for (i in 1:length(geneNames))
for (j in 1:length(geneNamesRevised))
if (geneNames[i]==geneNamesRevised[j])
{
break
}
else if ((j==length(geneNamesRevised)-1) &&
(geneNames[i]!=geneNamesRevised[j]))
{
geneNamesRevised[counter]=geneNames[i]
counter++
}
The error message is a repetitive string of :
the condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be usedthe condition has length > 1 and only the first element will be used
and this error message is for the last "else if" statement that has the '&&'.
Thank you!
Why not just
geneNamesRevised <- unique( geneNames )
... which returns a shortened list. There is also a duplicated function that can be used to remove duplicates when negated.
There are a few problems in your code.
1) The else is incorrectly specified - or not :) thanks #Mohsen_Fatemi
2) & is usually what you need rather than &&
3) counter++ isn't R
Copy the code below and see if it runs
for (i in 1:length(geneNames)){
for (j in 1:length(geneNamesRevised)){
if (geneNames[i]==geneNamesRevised[j])
{
break
} else {
if ((j==length(geneNamesRevised)-1) & (geneNames[i]!=geneNamesRevised[j]))
{
geneNamesRevised[counter]=geneNames[i]
counter <- counter + 1
}
}
}
}
Edit
4) also you were missing braces for your fors
use & instead of && ,
else if ((j==length(geneNamesRevised)-1) & (geneNames[i]!=geneNamesRevised[j]))
Background
I'm developing a function that takes in a value for w between 1 and 3 and returns n values from one of 3 distributions.
The problem I am having is when n or w are not of length 1. So I've added 2 parameters nIsList and wIsList to create the functionality I want. The way I want this to work is as follows:
(Works as needed)
If nIsList ex( c(1,2,3) ) return a list equivalent to running consume(w,1), consume(w,2), consume(w,3)
(Works as needed)
If wIsList ex( c(1,2,3) ) return a list equivalent to running consume(1,n), consume(2,n), consume(3,n)
(Doesn't work as needed)
If nIsList ex(1,2,3) and wIsList ex(1,2,3)
return a list equivalent to running consume(1,1), consume(2,2), consume(3,3). Instead, I get a list equivalent to running [consume(1,1), consume(1,2), consume(1,3)], [consume(2,1), consume(2,2), consume(2,3)], [consume(3,1),consume(3,2), consume(3,3)]
I understand why I am getting the results I am getting. I just can't seem to figure out how to get the result I want. (As explained above)
Question
I want the function to provide a list for each element in w and n that is consume(w[i], n[i]) when wIsList & nIsList are True. Is there a way to do that using lapply?
The code:
library("triangle")
consume <- function(w, n=1, nIsList=F, wIsList=F){
if(!nIsList & !wIsList){
if(w==1){
return(rtriangle(n,0.3,0.8))
}else if(w==2){
return(rtriangle(n,0.7,1))
}else if(w==3){
return(rtriangle(n,0.9,2,1.3))
}
}
else if(nIsList & !wIsList){
return(sapply(n, consume, w=w))
}
else if(nIsList & wIsList){
return(lapply(n, consume, w=w, wIsList=T))
}
else if(!nIsList & wIsList){
return(lapply(w, consume, n))
}
}
Note: I am having trouble summarizing this question. If you have any suggestions for renaming it please let me know and I will do so.
Thanks to JPC's comment, using mapply does the trick. The new code is as follows:
consume <- function(w, n=1){
nIsList <- length(n) > 1 # Change based on JPC's second comment
wIsList <- length(w) > 1 # Change based on JPC's second comment
if(!nIsList & !wIsList){
if(w==1){
return(rtriangle(n,0.3,0.8))
}else if(w==2){
return(rtriangle(n,0.7,1))
}else if(w==3){
return(rtriangle(n,0.9,2,1.3))
}
}
else if(nIsList & !wIsList){
return(sapply(n, consume, w=w))
}
else if(nIsList & wIsList){
return(mapply(consume,w,n)) ## Updated portion
}
else if(!nIsList & wIsList){
return(lapply(w, consume, n))
}
}