I am trying to create a for loop in R that will 1) identify a negative number is a column, 2) flip the sign to positive, 3) then flip the sign (in either direction) of select columns for the same row, and then create a factor identifying whether the signs were flipped for not.
Below is an example. I want all negative values in column "z" to become positive, and then for any row where this occurred (rows 4-8) I want the sign of values in column "y" flipped.
Example <- data.frame(x = 4:-3, y = -4:3, z = 2:-5)
x y z
1 4 -4 2
2 3 -3 1
3 2 -2 0
4 1 -1 -1
5 0 0 -2
6 -1 1 -3
7 -2 2 -4
8 -3 3 -5
for (i in Example$z){
if(sign(i) == -1){
Example$z[i] <- (Example$z[i]*-1)
Example$y[i] <- (Example$y[i]*-1)
Example$Flip[i] <- "True"
}
else{
Example$Flip[i] <- "False"
}
}
However, this for loop gives me the following:
x y z Flip
1 4 -4 2 True
2 3 -3 1 True
3 2 -2 0 True
4 1 -1 -1 True
5 0 0 -2 True
6 -1 -1 3 True
7 -2 -2 4 True
8 -3 -3 5 True
What I wanted it to create is this:
x y z Flip
1 4 -4 2 False
2 3 -3 1 False
3 2 -2 0 False
4 1 1 1 True
5 0 0 2 True
6 -1 -1 3 True
7 -2 -2 4 True
8 -3 -3 5 True
What am I doing wrong in the construction of this loop? Any help is greatly appreciated!
In R, most of the times you can get away without using for
loop
Example$Flip <- Example$z < 0
Example$z[Example$Flip] <- -Example$z[Example$Flip]
Example$y[Example$Flip] <- -Example$y[Example$Flip]
Example
# x y z Flip
#1 4 -4 2 FALSE
#2 3 -3 1 FALSE
#3 2 -2 0 FALSE
#4 1 1 1 TRUE
#5 0 0 2 TRUE
#6 -1 -1 3 TRUE
#7 -2 -2 4 TRUE
#8 -3 -3 5 TRUE
Using dplyr
we could get this done in one chain operation
library(dplyr)
Example %>%
mutate(Flip = z < 0,
z = ifelse(Flip, -z, z),
y = ifelse(Flip, -y, y))
As far as your for
loop is concerned you are looping over values of z
instead the looping should be on index of z
or the rows of dataframe (1:nrow(Example)
) instead. I made two changes in your code and the below should work.
Example$Flip = NA
for (i in seq_along(Example$z)){ #Change1
if(sign(Example$z[i]) == -1){ #Change2
Example$z[i] <- (Example$z[i]*-1)
Example$y[i] <- (Example$y[i]*-1)
Example$Flip[i] <- "True"
}
else{
Example$Flip[i] <- "False"
}
}
Example
# x y z Flip
#1 4 -4 2 False
#2 3 -3 1 False
#3 2 -2 0 False
#4 1 1 1 True
#5 0 0 2 True
#6 -1 -1 3 True
#7 -2 -2 4 True
#8 -3 -3 5 True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With