trying to plot the following function over the interval [-1,1] but am getting error code:
"Warning messages:
1: In if (g < a) { :
the condition has length > 1 and only the first element will be used
2: In if (g >= a & g <= b) { :
the condition has length > 1 and only the first element will be used"
unifCDF<-function(g) {
if (g< a) {
0
}
else if (g>=a & g<=b) {
(g-a)/(b-a)
}
else if (g>b) {
1
}
}
I know the function itself works since unifCDF() works for all values I tested. Any ideas?
Your function works on single values:
> unifCDF(.5)
[1] 0.75
but not on vectors:
> unifCDF(c(0.2,.3))
[1] 0.60 0.65
Warning messages:
1: In if (g < a) { :
the condition has length > 1 and only the first element will be used
2: In if (g >= a & g <= b) { :
the condition has length > 1 and only the first element will be used
and plot.function needs functions to work on vectors. The lazy way is to just Vectorize your function:
> unifCDF=Vectorize(unifCDF)
> unifCDF(c(0.2,.3))
[1] 0.60 0.65
> plot.function(unifCDF,-1,1)
which then works.
The right way is to code it so that it handles vector arguments naturally.
unifCDF = function(g){
res = (g-a)/(b-a)
res[g<a]=0
res[g>b]=1
res
}
in this code, res is always a vector of the same length as g. The first line computes the slopey bit for all values of g, and then the next two lines set the relevant bits outside the (a,b) limits to 0 and 1.
Note that having global variables, like a and b are generally a bad thing.
Related
I want write R code for Pythagoras theorem.
The Pythagorean Theorem states that the square of the hypotenuse (the side opposite the right angle) is equal to the sum of the squares of the other two sides.
(sideA)^2+(SideB)^2=hypotenuse^2
Now I wrote the R code as below:
pythag<-function(sidea,sideb){
if (sidea>=0&sideb>=0)
hypoteneuse=sqrt(sidea^2+sideb^2)
else if (sidea<0|sideb<0)
hypoteneuse<-"Values Need to be Positive"
else if (!is.vector(x))
hypoteneuse<-"I need numeric values to make this work"
print(hypoteneuse)
}
pythag(4,5)
pythag("A","B")
pythag(-4,-5)
In case of pythag(4,5) it is ok, also pythag(-4,-5) is giving comment "Values Need to be Positive".
But in case of pythag("A","B") I want comment "I need numeric values to make this work", but unfortunately my code does't work for this.
You can try like this:
get_hypotenuse_length <- function(height, base)
{
sides <- c(height, base)
if(any(sides < 0))
{
message("sides must be positive")
} else if(!is.numeric(x = sides))
{
message("sides can not be non-numeric")
} else
{
sqrt(x = sum(sides ^ 2))
}
}
Here's an annotated version. It is creating the function which takes the values a and b and calculates c. It is first testing if the values are numeric, if they are not numeric it will print your error message, otherwise it will ignore what is within those curly brackets and move on to the next test. The second test is checking that both are greater than zero (seeing as a triangle can't have a side of length zero or negative length). If it satifies the condition that both are >0 then it will calculate c, if not it will give the error stating that there are negative values.
# Feed it the values a and b (length of the two sides)
pythag <- function(a,b){
# Test that both are numeric - return error if either is not numeric
if(is.numeric(a) == FALSE | is.numeric(b) == FALSE){
return('I need numeric values to make this work')}
# Test that both are positive - return length of hypoteneuese if true...
if(a > 0 & b > 0){
return(sqrt((a^2)+(b^2)))
}else{
# ... give an error either is not positive
return('Values Need to be Positive')
}
}
Here's a more streamlined version:
pythag <- function(a,b){
if(is.numeric(a) == FALSE | is.numeric(b) == FALSE){return('I need numeric values to make this work')}
if(a > 0 & b > 0){return(sqrt((a^2)+(b^2)))}
else{return('Values Need to be Positive')}
}
And this is what it returns with your examples:
> pythag(4,5)
[1] 6.403124
> pythag("A","B")
[1] "I need numeric values to make this work"
> pythag(-4,-5)
[1] "Values Need to be Positive"
if x = c("sideA", "sideB"), then it will still be a vector so your test is.vector(x) will return true:
> is.vector(x)
[1] TRUE
But you want to test if it's numbers, so if it's numeric:
> is.numeric(x)
[1] FALSE
I'm trying to do many conditional events in R but im getting the warning:
Warning messages:
1: In if (closeV > openV) { :
the condition has length > 1 and only the first element will be used
2: In if ((highV - closeV) < Minimum) { :
the condition has length > 1 and only the first element will be used
3: In if ((openV - lowV) > Threshold) { :
the condition has length > 1 and only the first element will be used
4: In if (((openV - lowV) < Threshold)) { :
the condition has length > 1 and only the first element will be used
5: In if ((closeV - openV) < Threshold) { :
the condition has length > 1 and only the first element will be used
6: In if ((closeV - lowV) < (Threshold * 2)) { :
the condition has length > 1 and only the first element will be used
this is a huge nest of ifs, it is not optimized right now but i cant get it to work because of that warning.
There are around of 40 ifs in that function, any idea of what i need to do to get around this warning?
The code looks something like this
if(closeV>openV)#1 First we check if we have a positive value
{
if((highV-closeV)<Minimum)
{
if((openV-lowV) >Threshold)
{
if((closeV-openV)<Threshold)
{
#3.1 This is a Hammer with positive movement
if((closeV-lowV)<(Threshold*2))
{
#3.1.1 not much movement
return(X*2)
}
else if((closeV-lowV)>(Treshold*2))
{
#3.1.2 a lot of movement
return(X*3)
}
}
else if((closeV-openV)>Threshold)
{
#3.2 Hammer but with a lot of movement
if((closeV-lowV)<(Threshold*2))
{
#3.2.1 not much movement
return(X)
}
else if((closeV-lowV)>(Treshold*2))
{
#3.2.2 a lot of movement
return(X*5)
}
}
}
else if(((openV-lowV)<Threshold)
and it keeps on going through a lot of possibilites
The issue is not the nested if-statements, but rather the data structure you feed into them: The warning tells you that the comparison operator is only applied to the first element of the data structure you feed into the if-statements.
While
a = seq(1, 10, 1)
b = seq(0, 18, 2)
if (a>b){
print(a)
} else{
print(b)
}
throws the same warning messages you get,
a = seq(1, 10, 1)
b = seq(0, 18, 2)
for (i in 1:10) {
if (a[i]>b[i]){
print(a[i])
} else{
print(b[i])
}
}
in contrast evaluates smoothly.
Also, please notice that although both pieces of code are evaluated, they give very different results.
I have two arrays:
wspolczynnik
and
waga_linkow
and I would like to enter the following instruction:
if (wspolczynnik > waga_linkow[n]){
print('jest ok ')
} else {
print('za male')
}
I get the following warning message:
[1] "za male"
Warning message:
In if (wspolczynnik > waga_linkow[n]) { :
the condition has length > 1 and only the first element will be used
How can I correct the instruction?
Your code is using the whole first vector, you need to add the [n] after both vectors in the if argument, for example:
A <- c(1,2,3,4)
B <- c(0,0,1,5)
n <- 1
if (A[n] == B[n]){
print('A equal to B')
} else {
print('A not equal to B')
}
You could return results for all entries of the two vectors (I.e. A[1] and B[1], A[2] and B[2]...) writing a function and using a for loop
print_func <- function(a, b){
if(a == b){
print('a equal to b')
}
if (a != b){
print('a not equal to b')
}
}
for(i in 1:4){
print_func(A[i], B[i])
}
However, my personal preference is to make a vectorised version.
A <- c(1,2,3,4)
B <- c(0,0,1,4)
R <- rep("Not Equal", 4)
R[A == B] <- "Equal"
R
I made a function to to compute the sum of I(Xi
my.ecdf<- function(x,y) {
if(!is.null(dim(y)))
stop("y has more than one dimension")
n<-length(x)
i<-1:n
p<-if(x[i]<y) 1 else {
0
}
(sum(p))/n
}
But when I run it with input (rnorm(11),6), I get this error:
Warning message:
In if (x[i] < y) 1 else { :
the condition has length > 1 and only the first element will be used
Any ideas? I'm new to r so sorry if it's something obvious. (Also I don't want to use the for loop)
There are a number of issues in your code:
1) Whats the point of x[1:length(x)] in the if statement? Right now these are meaningless and can be dropped:
n<-length(x)
i<-1:n
x[i]
2) If statement accepts a logical argument not a vector of logical, you can consider adding all() any() etc like
if(all(x < y)) 1 else {0}
or use ifelse() statement for the assignment
3) Finally from what I can understand you overcomplicate things and the whole thing can be written as one-liner:
sum(x < y)/length(x)
This is a logical vector of the same length as y
is.null(dim(y))
You're using it as a logical test. An object with a length greater than 1 can't be unambiguously interpreted by the if statement. Consider if (TRUE FALSE FALSE TRUE) <do something>. When should you do that thing?
If you want to make sure y doesn't have more than one dimension, do
if(length(dim(y)) > 1){
stop("message")
}
I am a Phd student in the university of Padua and I am trying to write a little script (the first!) in R cran v. 3.0.1 to make a simulation on epidemiology.
I'd like to change the values of a vector of 883 values basing on a neighbour matrix constructed with nb2mat from a shapefile: if i and j (two cells) are neighbour (matrix) and i or j have a positive value in the vector, I'd like to transform the value of both i and j to 1 (positive), otherwise the value of i and j should remain 0. When I launch the next little script:
for(i in 1:883)
{ for(j in 1:883)
{ if(MatriceDist[i,j] > 0 & ((vectorID[i] > 0 | vectorID[j] > 0)) {
vectorID[i] = 1 & vectorID[j] = 1
print(vectorID)
} } }
the answer from the software is:
Error: unexpected '{' in:
" { for(j in 1:883)
{ while(MatriceDist[i,j] > 0 & ((vectorID[i] > 0 | vectorID[j] > 0)) {"
I think that it is an error in the statement for if but I can not understand how to solve it...
Thank you everyone!
Elisa
check your brackets :-)
for(i in 1:883) {
for(j in 1:883) {
if(MatriceDist[i,j] > 0 & (vectorID[i] > 0 | vectorID[j] > 0)) { vectorID[i] = 1 & vectorID[j] = 1 print(vectorID)
}
}
}
you had one ( to mucch before vectorID in your if statement.
please double check is the condition now specified in the statement is still the one you require.
btw: for loops are very slow in R. If you know the end size of vectorID, try pre-allocating the full matrix. That will speed things up a little bit.