Reputation: 1076
Suppose I have a data.frame called df
:
df <- data.frame(
A = 1:8,
B = rep(letters[1:4], each = 2),
C = rep(1:2, 4)
)
A B C
1 1 a 1
2 2 a 2
3 3 b 1
4 4 b 2
5 5 c 1
6 6 c 2
7 7 d 1
8 8 d 2
I want to swap the values in column B
, when they are b
or c
, but not when they are a
or d
, conditioned on another column C
, i.e., when C = 1
. So the target data.frame is df1
:
df1 <- data.frame(
A = 1:8,
B = c("a", "a", "c", "b", "b", "c", "d", "c"),
C = rep(1:2, 4)
)
A B C
1 1 a 1
2 2 a 2
3 3 c 1
4 4 b 2
5 5 b 1
6 6 c 2
7 7 d 1
8 8 c 2
Upvotes: 3
Views: 148
Reputation: 51612
You can try chartr
,
chartr('bc', 'cb', df$B)
#[1] "a" "a" "c" "c" "b" "b" "d" "d"
To condition it on C == 1
then,
df$B[df$C == 1] <- chartr('bc', 'cb', df$B[df$C == 1])
Upvotes: 6
Reputation: 2934
dplyr
provides recode
to replace multiple values at once as shown below. Based on the new requirement in your question, I have updated the code below to provide with desired output:
> library(dplyr)
> df
A B C
1 1 a 1
2 2 a 2
3 3 b 1
4 4 b 2
5 5 c 1
6 6 c 2
7 7 d 1
8 8 d 2
> for(i in 1:nrow(df)) {
if(df$C[i] == "1") {
df$B[i] <- recode(df$B[i], 'b' = 'c', 'c' = 'b')
}
}
> df
A B C
1 1 a 1
2 2 a 2
3 3 c 1
4 4 b 2
5 5 b 1
6 6 c 2
7 7 d 1
8 8 d 2
Upvotes: 0
Reputation: 79348
a=which(df$B%in%letters[2:3]&df$C==1)
df[a,2]=df[rev(a),2];df
A B C
1 1 a 1
2 2 a 2
3 3 c 1
4 4 b 2
5 5 b 1
6 6 c 2
7 7 d 1
8 8 d 2
Upvotes: 0
Reputation: 32558
gsub("_", "", ifelse(df$B == "b", "_c", ifelse(df$B == "c", "_b", as.character(df$B))))
#[1] "a" "a" "c" "c" "b" "b" "d" "d"
Upvotes: 0
Reputation: 3140
# this will work generally
ic <- df$B == 'c'
ib <- df$B == 'b'
df$B[ic] <- 'b'
df$B[ib] <- 'c'
> df
A B
1 1 a
2 2 a
3 3 c
4 4 c
5 5 b
6 6 b
7 7 d
8 8 d
Upvotes: 2