3-section transformation function in R - r

I hope this question is new as I couldn't find a solution that worked for me.
I have a vector x that can be filled with any real numbers. The elements in this vector should be transformed by a function in the following way:
x = 0, if x < a
x = (x-a)/(b-a), if a <= x <= b
x = 1, if x > b
This is the function I came up with:
transf <- function(x, a = 0, b = 1){
if(a > b) stop("\nThe lower bound must be smaller than the upper bound!")
if(x < a){
y = 0
}
else if(a <= x <= b){
y = (x-a)/(b-a)
}
else{
y = 1
}
return(y)
print(y)
}
I get a bunch of error messages that I can't quite put together. I also tried replacing else if and else with a simple if, but that didn't work either.
Any help on how to solve this would be very much appreciated

I'd use logical indexing:
i.low <- x < a
i.mid <- x >= a & x <= b
i.high <- x > b
x[i.low] <- 0
x[i.mid] <- (x[i.mid] - a) / (b - a)
x[i.high] <- 1
Your original post didn't say what the errors were, but I'd guess you were passing the vector in as your function argument and the errors were complaining "the condition has length > 1 and only the first element will be used". This is because you're testing the condition of a vector of logicals.

Related

How to store values in a vector inside a while loop in R

For the next exercise: From a certain numerical value, check if this is a natural number or not so that, if it is, it shows the divisors of this number and, if it is not, it shows an error message.
As there was no predefined function for this I wrote:
n <- 102
x <- n
res <- c()
while (x>0){
if (n%%x == 0){
res[x] <- x
x = x-1
} else {
x = x -1
} print("The values are ", res)
}
res
Works nice, except it´s not storing the values inside the vector. Any ideas?
I´m new to programming and stackoverflow. I hope this question is right posted and presented.
Cheers
What you need is a counter "i" to save the value in the next entry of the vector
n <- 102
x <- n
res <- c()
i<-1
while (x>0){
if (n%%x == 0){
res[i] <- x
x = x-1
i<-i+1
} else {
x = x -1
}
}
res

Sorting a vector in R without using sort function

I am trying to write a function to sort a vector, but without using R's inbuilt 'Sort' function.
My Code:
sorting <- function(x){
for(i in 1:length(x)){
for(j in (i+1):length(x)){
if(x[i] > x[j]){
x[c(i,j)] = x[c(j,i)]
}
}
}
x
}
I get below output:
> x <- c(3,1,4,7,2,9)
> sorting(x)
Error in if (x[i] > x[j]) { : missing value where TRUE/FALSE needed
>
I understand that we'll get above error when the 'IF' condition returns 'NA' instead of TRUE/FALSE.
Is there an issue with the statement:
for(j in (i+1):length(x)){
Python code for same:
def sorting(a):
for i in range(len(a)):
for j in range(i+1,len(a)):
if a[i] > a[j]:
a[i],a[j] = a[j],a[i]
return a
Output:
sorting([3,1,4,7,2,9])
Out[380]: [1, 2, 3, 4, 7, 9]
In Python, the code works fine.
Could someone let me know the issue with my R code.
The problem is with that (i+1). When length(x) reaches its max value, j goes out of range. I added this: (length(x)-1).
sorting <- function(x){
for(i in 1:(length(x)-1)){
for(j in (i+1):length(x)){
if(x[i] > x[j]){
x[c(i,j)] = x[c(j,i)] # +1 for this
}
}
}
x
}
sorting(c(3,1,4,7,2,9))
[1] 1 2 3 4 7 9
Sorting <- function(x){
xs <- rep(0, length(x))
for(i in 1:length(x)){
xs[i] = min(x)
x <- x[x != min(x)]
}
xs
}
Sorting(c(3,1,4,7,2,9))
[1] 1 2 3 4 7 9
Sorting is a function with a numeric vector argument x. Initially xs, the sorted vector of the same length as x, is filled with zeroes. The for loop aims at assigning the minimum value of vector x to each component of xs (for(i in 1:length(x)){ xs[i] = min(x) ). We then remove such minimum value from x by x <- x[x != min(x)] } to find the next minimum value. Finally, xs shows the sorted vector of x.

Summation of max function with vector input in R?

I want to build this function: f(a,b)=sum_{i=1 to n}(max(a-b_i,0)) where b=(b_1,b_2,...b_n). This is what I have done:
vec<-function(a,b){
z<-0
for(i in b){
ifelse(a > i,z <- z + (a-i), 0)
}
return(data.frame(z))
}
This code gives correct output for scalar input of a. But while using vector output answers are not always correct. For example
> vec(c(-6,5),c(3,1,3))
gives -25 for a=-6 and 8 for a=5 respectively.
But > vec(-6,c(3,1,3)) gives 0. And this the correct answer.
Please throw give some idea how will I correct it.
When you let a = c(-6,5), then this argument a > i becomes (FALSE, TRUE). Since it contains a true, the vector is passed into z <- z + (a-i). Note that if you use a=-6 in this formula, you get the output of -25. I would suggest doing something like this:
vec<-function(a,b){
z<-0
for(i in b){
p <- ifelse(a > i,z <- z + (a-i), 0)
}
return(data.frame(p))
}
I believe that what you are missing is the condition on only summing up positive numbers, as expressed by the condition 'max(a-b_i, 0)'.
This code works fine for the examples you provide:
vec <- function(a, b){
n <- NULL
for(i in 1:length(a)){
z <- a[i] - b
z <- z[z > 0]
n <- c(n, sum(z))
}
return(n)
}
For example:
> vec(c(-6, 5), c(3, 1, 3))
[1] 0 8
and
> vec(-6, c(3, 1, 3))
[1] 0
If you want to get a data.frame back just replace the return(n) instruction to return(data.frame(n)).

R: Defining a function in R including a for loop and if condition

let's consider for example the following vector in R: x <- 2*c(1:100).
Now I want to define a stepwise function which should attain the value x[1] = 2 for x if x >= 0 & x < 1´, the x[2] = 4 for x if x >= 1 & x < 2´....
I tried to do this with the following code:
y <- 2*c(1:100)
f <- function(x){for(i in 1:100){if((x >= i-1) & (x < i)){y[i]}
}
}
This didn't work - what is wrong with my code?
Thanks in advance.
First of all, you miss a closing bracket in if condition. It should be like this:
if((x >= i-1) & (x < i))
Second of all, your function uses x as an argument as well as an external vector's name. That's confusing.
Third of all,
function(y) x[floor(y)]
would be more efficient

Why is this if/else error appearing in script but not in console?

In this piece of code:
q7 <- function (x) {
if (is.numeric (x) == FALSE) {stop ("Input is non-numeric.")}
if (all (x > 0) == FALSE) {stop ("Input has negative values.")}
sum <- 0
while (sum <= 100) {
if (x[1] > 50) {next}
else if (x[1] %% 2 == 0) {sum <- sum + (x[1] / 2)}
else {sum <- sum + x[1]}
x <- x [x[2]:length (x)]
}
}
Used for example as q7 (c(10,20,30,40,50,60,70,80,90,100)), I get this error:
Error in if (x[1] > 50) { : missing value where TRUE/FALSE needed
I think the condition here couldn't be simpler and I must be missing some R heuristic, because obviously in the console;
> x <- c(10,20,30,40,50,60,70,80,90,100)
> x[1] > 50
[1] FALSE
So simple.
What is going on?
A quick diagnose with debug shows the problem is with
x <- x[x[2]:length(x)]
After the first iteration this will be a vector of NA. Then in the next iteration, when you check x[1] > 50, you are in fact doing NA > 50, thus you get the error.
After checking with you, you simply want to remove the first value of x. So why not use
x <- x[-1]
Changing x[2] to just 2 will do it.
x <- x [2:length (x)]
Because of the 'next' statement you will end up with an infinite loop, since from x[1] = 60 onward, it will keep moving to the next iteration of the while loop (forever). Maybe you wanted to use 'break'.

Resources