R function length error message - 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")
}

Related

Pythagorean Theorem in R programming

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

Difficulty with recursively adding non-whole number

I am new to R and I am having difficulty with a simple recursion function. I initialize a variable, x to .1 and then make a call to a recursive function in which if x is not equal to the user-input number, it will add .1 to x and recursively call the function again. If x is greater than the input number, the function returns an error message.
I have tried setting x to a whole number, mainly 1 and then trying to evaluate the function. This process works, so I figure that there is an issue of adding decimal numbers to each other and then evaluating their equality with a whole number.
u<-function(a)
{
#Initialize r
x<-.1
#Call to recursive method
v(a, x)
}
#Recursive function
v<-function(a, x)
{
#Check for current value of a and r
print(a)
print(x)
if(a==x) {
return("Yes")
}
else if(a < x) {
return("Error!")
}
else{
x<-x+.1
v(a, x)
}
}
When I set a to 1, I would expect the function to return "Yes" after recursing until x is equal to 1 as well. However, this is not the case. The function then recurses once more, setting x to 1.1 and returns the message "Error!".
I think you are running into issues with floating point precision. If you use a function designed to check equality while accounting for floating point precision, like dplyr::near(), the function gives the expected result:
v<-function(a, x)
{
#Check for current value of a and r
print(a)
print(x)
if(dplyr::near(a, x)) {
return("Yes")
}
else if(a < x) {
return("Error!")
}
else{
x<-x+.1
v(a, x)
}
}

Error in if (num < 0) { : missing value where TRUE/FALSE needed

y <- as.integer(readline(prompt ="Enter a number: "))
factorial = 1
if (y< 0){
print("Error")
} else if (y== 0)
{
print("1")
} else
{
for(i in 1:y) {
factorial = factorial * i
}
return(factorial)
}
wondering why this is giving:
Error in if (y< 0) { : missing value where TRUE/FALSE needed
is it cause the first line has data type NA_integer?
There are three possible ways to pass values to the if statement.
y <- 1
if (y > 0) print("more")
This one works as expected.
y <- 1:3
if (y > 0) print("ignores all but 1st element")
As the warning message will tell you, only the first element was used to evaluate it. You could use any or all to make this right.
y <- NA
if (y > 0) print("your error")
This case actually gives you your error. I would wager a bet that y is somehow NA. You will probably need to provide a reproducible example (with data and the whole shebang) if you'll want more assistance. Note also that it helps visually structure your code to improve readability.

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.

How to apply a function that take multiple arguments which are both vectors?

chance<-c(0.11,0.12,0.13,0.14,0.15)
aaa<-function(x,y) {
assignChance <- function (a,b,v) {
if (a == 0)
if (b == 0) 1-v
else v
else
if (b == 0) 0
else 1
}
sapply(x,assignChance,y,chance) # this is wrong
}
aaa(c(1,1,0,0,1),c(1,1,1,0,0))
I would expect the outcome as: 1, 1, 0.13, 0.86, 0
Is there any better way for this function. I feel my current attemp is quite ugly as in a functional language I can just use Array.map3 plue pattern match.
Is there a vector version of switch just like ifelse?
You are looking for mapply :
mapply(assignChance,x,y,chance)
By using sapply in your code, you are applying the assignChance function to every element of x in turn, and you are passing as b and v arguments your whole vectors y and chance. So, for example, for the first iteration of your sapply, the resulting call will be :
assignChance(x[1],y,chance)
instead of :
assignChance(x[1],y[1],chance[1])

Resources