Adding indicator values by using a for loop in R - r

I'm relatively inexperienced with R. I have a vector of true and false values. I want to make these numeric (i.e., 0 or 1). I have tried to write this for loop, but there are several syntax errors that I don't know how to fix.
indY <- rep(NA, nrow(dat)) # making an empty vector
# use for loop to fill each entry with either 0 or 1
for (i in 1:length(y)) {
if newy[i] == TRUE:
indY[i] == 1
else:
indY[i] == 0
}
Any suggestions? Thanks.

This should be fine :
as.numeric(y)
Assuming y is a vector of TRUEs and FALSEs.

For bonus points, use +:
y <- c(TRUE, TRUE, FALSE, TRUE)
+y
#[1] 1 1 0 1
This coerces y to numeric and returns the vector.

Try:
df$y <- ifelse(df$y, 1, 0)

Related

Performing operation along vector in R - only returns a single value

I'm trying to perform a conditional operation on a vector xt, given a value lambdat.
Outside of the ifelse() function the operations work, but the full code doesn't. See example below, cheers!
xt <- c(1,2,3)
lambdat <- 1
bc_applied_columnt <- ifelse(lambdat != 0, (xt^(lambdat)-1)/lambdat, log(xt))
This returns 0 (first value in the vector xt), but I'd like it to return the output of (xt^(lambdat)-1)/lambdat or log(xt) - depending on the condition.
ifelse returns the output of the same length as the condition that you check. Since length(lambdat != 0) is of length 1 ifelse returns output of length 1 as well. When you have only one value to check use if/else.
xt <- c(1,2,3)
lambdat <- 1
if(lambdat != 0) (xt^(lambdat)-1)/lambdat else log(xt)
#[1] 0 1 2

Vector of elements not being updated within loop

logically this code should make sense, I'm primarily a python programmer but I'm unsure why this is not working. It is not returning any errors. What I want is for this vector of primarily zeros to be changed to a vector of only 1's and -1's (hence using the sample function). My issue is that the values of the vector are not being updated, they are just staying as 0 and I'm not sure why.
Y = numeric(100)
for (i in 100){
x <- sample(1:2, 1)
if (x == 2){
Y[i] = 1
}
else{
Y[i] = -1
}
}
I've also changed the Y[i] = 1 to Y[i] <- 1 but this has not helped. I also know that x is either 1 or 2 because I test it manually using x == 2...etc
The only other issue I could think of is that x is an integer while the numbers sample returns are not but per checking this: (Note that x = 2L after the loop exited)
> typeof(x)
[1] "integer"
> typeof(2)
[1] "double"
> x == 2
[1] TRUE
I don't think it is the problem.
Any suggestions?
Because the loop is just run once i.e. the last iteration. It did change in the output vector Y
tail(Y)
#[1] 0 0 0 0 0 -1
Instead it would be 1:100
for(i in 1:100)
The second issue raised is with the typeof 'x'. Here, we are sampleing an integer with 1:2 instead of a numeric vector and that returns the same type as the input. According to ?':'
For numeric arguments, a numeric vector. This will be of type integer if from is integer-valued and the result is representable in the R integer type, otherwise of type "double"
typeof(1:2)
#[1] "integer"
typeof(c(1, 2))
#[1] "double"
Another option if it is a range (:) is to wrap with as.numeric
for (i in 1:100){
x <- sample(as.numeric(1:2), 1)
if (x == 2){
Y[i] = 1
}
else{
Y[i] = -1
}
}
check the type
typeof(Y)
#[1] "double"
typeof(x)
#[1] "double"
Also, R is a vectorized language so this:
x<-sample(1:2, 100, replace = TRUE)
Y<-ifelse(x==2, 1, -1)
will run about 1000 times faster than your loop.

Ranks and identification of elements in r

I have two vectors with different elements, say x=c(1,3,4) , y= c(2,9)
I want a vector of ranges that identifies me the elements of vector x with 1 and those of y with 0, ie
(1,2,3,4,9) -----> (1,0,1,1,0)
How could you get the vector of zeros and ones (1,0,1,1,0) in r?
Thanks
The following option surely isn't numerically optimal, but it's the most simple and direct one:
a<-c(1,2,3,4)
b<-c(5,6,7,8)
f<-function(vec0,vec1,inp)
{
out<-rep(NA,length(inp)) #NA if input elements in neither vector
for(i in 1:length(inp))
{ #Logical values coerced to 0 and 1 at first, then
if(sum(inp[i]==vec0))(out[i]<-0); #summed up and if sum != 0 coerced to logical "TRUE"
}
for(i in 1:length(inp))
{
if(sum(inp[i]==vec1))(out[i]<-1);
}
return (out)
}
Works just fine:
> f(vec0=a,vec1=b,inp=c(1,6,4,8,2,4,8,7,10))
[1] 0 1 0 1 0 0 1 1 NA
first you define a function that do that
blah <- function( vector,
x=c(1,3,4),
y= c(2,9)){
outVector <- rep(x = NA, times = length(vector))
outVector[vector %in% x] <- 1
outVector[vector %in% y] <- 0
return(outVector)
}
then you can use the function:
blah(vector = 1:9)
blah(vector = c(1,2,3,4,9))
you can also change the value of x & y
blah(vector = 1:10,x = c(1:5*2), y = c((1:5*2)-1 ))

R programming language LOOPS

y <- vector()
i <- 5
while((2<3)<i){
y[i] <- "Hello World!"
i <- i-1 }
y
So I didn't understand how to while loop works when while((2<3)<i) is the case, 2<3 is true for all conditions and i end up with TRUE<i, what does this mean? Or am I thinking wrong?
I just didn't get how to condition of the while loop works, if I get that I believe I will work it out.
Also another question:
xxx <- function(vec){
n <- length(vec)
}
for(i in 1:n){
x <- vec[i]
if (vec[i]<x){
x <- vec[i]
}
} return(x)
This xxx function is suppose to output the minimum value of the function? okay i see but how?
when we enter the loop we first do x<- vec[i] without doing this we can't pass to the next command the if statement right? so since we do x <- vec[i] earlier if command won't work probably since x==vec[i] all the time.
Please help guys since iI have the exam tomorrow :(
1) ?Comparison says, referring to the two arguments of any comparison operator such as < :
If the two arguments are atomic vectors of different types, one is
coerced to the type of the other, the (decreasing) order of precedence
being character, complex, numeric, integer, logical and raw.
so in this case we have one logical argument and one numeric argument so the the logical argument is coerced to numeric (where FALSE is converted to 0 and TRUE is converted to 1). Thus (2<3)<5 is the same as TRUE < 5 which is the same as 1 < 5 which is TRUE:
(2<3)<5
## [1] TRUE
2) For xxx you probably want this:
xxx <- function(vec) {
x <- Inf
for(i in seq_along(vec)) if (vec[i] < x) x <- vec[i]
x
}
The first statement in the body assigns Inf to x In the second statement in the body seq_along(vec) is 1, 2, ..., length(vec) so the for loop iterates i over 1, 2, ..., length(vec) with each iteration replacing x with vec[i] if vec[i] is less than x. Note that if vec has zero length then the loop is not run at all since seq_along(vec) has zero length.
Testing it out:
> xxx(1:3)
[1] 1
> xxx(3:1)
[1] 1
> xxx(numeric(0)) # zero length input
Inf
Of course R already has the min function which does the same thing.

Fastest way to find switching from positive to negative in a vector in R

I have a vector that contains both positive and negative values. For example something like
x = c(1,2,1,-2,-3,3,-4,5,1,1,-3)
And now I want to flag the indices of the vector where the value changes from positive to negative or negative to positive. So in the example above I would want something a vector of indices that looks something like this
y=c(0,0,0,1,0,1,1,1,0,0,1)
I am doing this in R so if possible I would like to avoid using for-loops.
I think this should work:
+(c(0, diff(sign(x))) != 0)
#[1] 0 0 0 1 0 1 1 1 0 0 1
all.equal(+(c(0, diff(sign(x))) != 0), y)
#[1] TRUE
Here's one way:
yy = rep(0, length(x))
yy[with(rle(sign(x)),{ p = cumsum(c(1,lengths)); p[ -c(1,length(p)) ] })] = 1
all.equal(yy,y) # TRUE
...which turned out more convoluted than I expected at first.

Resources