How to fix errors in this function - r

Write a function named countConsecutivePairs that accepts a numeric vector as an argument and counts the pairs of consecutive elements whose difference is less than 2.
You should stop the execution and print an appropriate error message if the argument is not numeric.
Here is my code
countConsecutivepairs=function(z){
if(!(is.vector(z)))
stop("Error"
if(class(z)!="numeric")
stop("Error")
for(i in z) {
if(abs(z[i]-z[i+1])!=2){
next
}
print(c(z[i],z[i+1])
}
}
I get a bunch of errors when I do this. And Im not sure how to fix it.

You miss several ) in your code.
And thanks to #Jan, as #Ace123 use z[i]'s in code and also want to check consecutive elements, we should call those elements by i against length of z.
countConsecutivepairs<- function(z){
if(!(is.vector(z))){
stop("Error")
}
if(class(z)!="numeric"){
stop("Error")
}
for(i in 1:(length(z)-1)) {
if(abs(z[i]-z[i+1])!=2){
next
}
print(c(z[i],z[i+1]))
}
}
countConsecutivepairs(c(1,2,3,5,7))
[1] 3 5
[1] 5 7

Related

How do you generate the output of for loop and if statement into a list or vector?

I have tried the following but the output brings an argument stating,
Error in append("0") : argument "values" is miss
for (rowz in final_data$Ingridients) {
Cobalt_row<-lst()
if (sum(str_detect(rowz, 'Cobalt'))>0) {
Cobalt_row.append(1)
} else {
Cobalt_row<-append(0)
}
print(Cobalt_row)
}
I intended to loop through the list and generate a boolean of ones and twos depending on
whether or not I had the value.
Please help
Without the data, I can't test it, but this should work:
Cobalt_row<-lst()
k <- 1
for (rowz in final_data$Ingridients) {
Cobalt_row[[k]] <- ifelse(str_detect(rowz, 'Cobalt'), 1, 0)
k <- k+1
}
or even simpler if you need a list:
Cobalt_row <- as.list(as.numeric(str_detect(final_data$Ingredients, "Cobalt")))

why c() does not working in this recursive function in R?

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

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

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

Check each argument exists as an input in a function

I am trying to make a function which gets few inputs. I would like to know how to check the availability of my arguments . Here is my function:
MyFunction<-function(data,window,dim,option) {
}
First, I want to see if there is any argument , if no, print an error
is it correct to use
if ~nargin
error('no input data')
}
Then, I want to make sure that the second argument is also inserted
is it right to ask like this
if nargin < 2
error('no window size specified')
}
Then, I want to check if the third argument is empty , set it as 1
if nargin < 3 || isempty(dim)
dim<-1
}
you can use hasArg()
testfunction <- function(x,y){
if(!hasArg(x)){
stop("missing x")
}
if(!hasArg(y)){
y = 3
}
return(x+y)
}
>testfunction(y=2)
Error in testfunction(y = 2) : missing x
> testfunction(x=1,y=2)
[1] 3
> testfunction(x=1)
[1] 4
As #Ben Bolker said , missing is used to test whether a value was specified as an argument to a function. You can have different conditions in your R functions such as warning or stop.
In your case, I would do the following
MyFunction<-function(data,window,dim,option) {
if (missing(data))
stop("the first argument called data is missing")
if (missing(window))
stop("the second argument called window is missing")
if (missing(dim))
dim <- 1
if (missing(option))
stop("the second argument called option is missing")
}

Resources