Pythagorean Theorem in R programming - r

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

Related

R function length error message

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")
}

Error message in Bubble sort code in R language

I did some programming work on R language to do the bubble sort. Sometimes it works perfectly without any error message, but sometimes, it shows "Error in if (x[i] > x[i + 1]) { : argument is of length zero". Can any one help me check whats wrong with it? I have attached my code below
example <- function(x) {
n <- length(x)
repeat {
hasChanged <- FALSE
n <- n - 1
for(i in 1:n) {
if ( x[i] > x[i+1] ) {
temp <- x[i]
x[i] <- x[i+1]
x[i+1] <- temp
hasChanged <- TRUE
cat("The current Vector is", x ,"\n")
}
}
if ( !hasChanged ) break;
}
}
x <-sample(1:10,5)
cat("The original Vector is", x ,"\n")
example(x)
The error occurs because you are iteratively decreasing n. Depending on the original vector's order (or lack thereof), n can reach the value of 1 after the last change. In that case, a further reduction of n in the next iteration step addresses the value x[0], which is undefined.
With a minimal correction your code will work properly, without giving error messages. Try to replace the line
if ( !hasChanged ) break;
with
if ( !hasChanged | n==1 ) break
Basically you have two termination criteria: Either nothing has been changed in the previous iteration or n is equal to one. In both cases, a further iteration won't change the vector since it is already ordered.
By the way, in R programming you don't need a semicolon at the end of a command. It is tolerated/ignored by the interpreter, but it clutters the code and is not considered good programming style.
Hope this helps.

Comparing two values in R

I am checking the input of a matrix is reciprocal in R, i.e. value on one side is = to 1/value..
So far I have..
AHP <- function(pairwisematrix){
## check the input data
if (!((is.matrix(pairwisematrix) || (is.data.frame(pairwisematrix)))))
stop("pairwise matrix must be a matrix or a data frame")
if (!(nrow(pairwisematrix) == ncol(pairwisematrix)))
stop("pairwise matrix must be a square matrix or a data frame")
for (i in 1:nrow(pairwisematrix)) {
for (j in 1:ncol(pairwisematrix)) {
if (i == j) { if (pairwisematrix[i,j] != 1) { stop("the central values in the reciprocal matrix must be 1.") }}
else { if ((pairwisematrix[i,j] == 1 / pairwisematrix[j,i]) || (pairwisematrix[j,i] == 1 / pairwisematrix[i,j])))) { stop("the pairwise matrix must be reciprocal (i.e. value on one side must = 1/value)") }}
}
}
out <- "all worked"
return(out)
}
but when I test:
check1 <- matrix(c(1,1/3,5,3,1,0.2,0.2,5,1),3,3,byrow=T)
test <- AHP(check1)
I get the error:
the pairwise matrix must be reciprocal (i.e. values on one side must =
1/value)0.333333 & 0.333333
I have tried converting the values to string, partial strings and tried identical(a,b,) with no success.
Does anyone have any ideas?
With many if s inside double for loops, I would be surprised if it works as intended.
R is designed for working with matrix, so you could write something like
AHP <- function(pairwisematrix){
if(!all(pairwisematrix == t(1/pairwisematrix)))
stop("the pairwise matrix must be reciprocal (i.e. value on one side must = 1/value)")
else
return("all worked")
}
AHP(check1)
#[1] "all worked"

nested if statment in R

I'm trying to implement following thing in R, but I'm new in R and my code doesn't work.
I have matrix A, I did coordinates changes .
I want to write two function:
1) give the element of matrix, given coordinates
2) give the coordinates given number.
the pseudo code is right, the only problem is my syntax. can somebody correct it ?
f<- as.numeric(readline(prompt="Please enter 10 to get coordinate of number,and 20 to get the number > "));
if(p==10){
# give the number, given coordinates
i<- as.numeric(readline(prompt="Pleae enter i cordinate > "));
j<- as.numeric(readline(prompt="Pleae enter j cordinate > "));
if (i>0&j<0) return A[5+i,5+j]
if (i>0&j>0) return A[5+i,5+j]
if (i<0&j>0) return A[5+i,5-j]
if (i<0&j<0) return A[5+i,5-j]
}else if (p==20){
#give the cordinate, given number
coordinate <- which(A==number)
[i,j]<-A[2-coordinate[0],coordinate[1]-2]
}
}
Warning: what if i or j is equal to zero? Next, make a single variable which is the decimal representation of binary i,j, That is,
if(p==10){
x <- (i>0) + 2*(j>0) +1
# x takes on values 1 thru 5. This is because switch requires nonnegative integer
switch(x,
return A[5+i,5+j],
return A[5+i,5+j],
return A[5+i,5+j],
return A[5+i,5+j]) # change the +/- indices as desired
}else{
#etc.
And, finally, you should make this a function, not a collection of commands.
Edit - I skipped this before, but: you cannot call an index of 0 so you need to fix a number of things in the line [i,j]<-A[2-coordinate[0],coordinate[1]-2]
The syntax is as follows:
x <- 4
if (x == 1 | x == 2) print("YES")

Solve equation, strange result

here is my code to solve equation:
fx=function(x){ x^3-x-3}
solve=function(a,b,eps){
if(abs(fx(a))<0.00001) return(list(root=a,fun=fx(a)))
else if(abs(fx(b))<0.00001) return(list(root=b,fun=fx(b)))
else if (fx(a)*fx(b)>0) return(list(root="failed to find"))
if (a>b){
c<-a
a<-b
a<-b}
while( b-a>eps ){
x=(a+b)/2
if (fx(x)==0) {return(list(root=x,fun=fx(x))) }
else if (fx(a)*fx(x)<0) {b=x }
else {a=x}}
myroot=(a+b)/2
return(list(root=myroot,value=fx(myroot)))
}
> solve(1,3,1e-8)
$root
[1] 1.6717
$value
[1] 2.674228e-08
> fx(1.6717)
[1] 8.73813e-07
Why fx(1.6717) != $value, I want to know the reason
8.73813e-07!=2.674228e-08?
how can i revise:return(list(root=myroot,value=fx(myroot)))
to make my root more digits ?
When R prints a value, it uses by default digits=3, i.e. printing 3 significant digits. This means you made an error of interpretation when looking at your results.
Try this:
x <- solve(1,3,1e-8)
print(x[[1]], digits=9)
[1] 1.67169989
Now substitute the actual returned value into your function:
fx(x[[1]])
[1] 2.674228e-08
Now the values match.
In summary, you have made a rounding error when interpreting the printed results of your function.
You can trace this behaviour in the R help files as follows:
?print
will point you to
?print.default
Which has this to say about the digits argument:
digits: a non-null value for digits specifies the minimum number of significant digits to be printed in values. The default, NULL, uses getOption(digits). (For the interpretation for complex numbers see signif.) Non-integer values will be rounded down, and only values greater than or equal to 1 and no greater than 22 are accepted.
Try this and look at the print() of a and b.
fx=function(x){ x^3-x-3}
solve=function(a,b,eps){
if(abs(fx(a))<0.00001) return(list(root=a,fun=fx(a)))
else if(abs(fx(b))<0.00001) return(list(root=b,fun=fx(b)))
else if (fx(a)*fx(b)>0) return(list(root="failed to find"))
if (a>b){
c<-a
a<-b
a<-b}
while( b-a>eps ){
x=(a+b)/2
if (fx(x)==0) {return(list(root=x,fun=fx(x))) }
else if (fx(a)*fx(x)<0) {b=x }
else {a=x}}
myroot=(a+b)/2
print(a,digits=20)
print(b,digits=20)
return(list(root=myroot,value=fx(myroot)))
}
There is a round.

Resources