I have a dataframe z
and I want to create the new column based on the values of two old columns of z
. Following is the process:
>z<-cbind(x=1:10,y=11:20,t=21:30)
> z<-as.data.frame(z)
>z
x y t
1 1 11 21
2 2 12 22
3 3 13 23
4 4 14 24
5 5 15 25
6 6 16 26
7 7 17 27
8 8 18 28
9 9 19 29
10 10 20 30
# generate the column q
which is equal to the values of column t
times 4 if x=3
and for other values of x
, it is equal to the values of column t
.
for (i in 1:nrow(z)){
z$q[i]=if (z$x[i]==4) 4*z$t[i] else z$t[i]}
But, my problem is that I want to apply multiple conditions:
For example, I want to get something like this:
(If x=2, q=t*2; x=4, q=t*4; x=7, q=t*3; for other it is equal to t)
> z
x y t q
1 1 11 21 21
2 2 12 22 44
3 3 13 23 23
4 4 14 24 96
5 5 15 25 25
6 6 16 26 26
7 7 17 27 81
8 8 18 28 28
9 9 19 29 29
10 10 20 30 30
How do I get the second output using the loops or any other method?
By building a nested ifelse
functional by recursion, you can get the benefits of both solutions offered so far: ifelse
is fast and can work with any type of data, while @Matthew's solution is more functional yet limited to integers and potentially slow.
decode <- function(x, search, replace, default = NULL) {
# build a nested ifelse function by recursion
decode.fun <- function(search, replace, default = NULL)
if (length(search) == 0) {
function(x) if (is.null(default)) x else rep(default, length(x))
} else {
function(x) ifelse(x == search[1], replace[1],
decode.fun(tail(search, -1),
tail(replace, -1),
default)(x))
}
return(decode.fun(search, replace, default)(x))
}
Note how the decode
function is named after the SQL function. I wish a function like this made it to the base R package... Here are a couple examples illustrating its usage:
decode(x = 1:5, search = 3, replace = -1)
# [1] 1 2 -1 4 5
decode(x = 1:5, search = c(2, 4), replace = c(20, 40), default = 3)
# [1] 3 20 3 40 3
For your particular problem:
transform(z, q = decode(x, search = c(2,4,7), replace = c(2,4,3), default = 1) * t)
# x y t q
# 1 1 11 21 21
# 2 2 12 22 44
# 3 3 13 23 23
# 4 4 14 24 96
# 5 5 15 25 25
# 6 6 16 26 26
# 7 7 17 27 81
# 8 8 18 28 28
# 9 9 19 29 29
# 10 10 20 30 30
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