Likan Zhan
Likan Zhan

Reputation: 1076

How do I swap a subset of values in one column, but leave other values in the same column unchanged?

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

Answers (5)

Sotos
Sotos

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

Sagar
Sagar

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

Onyambu
Onyambu

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

d.b
d.b

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

Petr Matousu
Petr Matousu

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

Related Questions