如何交换一列中的值子集,但保持同一列中的其他值不变?

  • 本文关键字:一列 其他 交换 何交换 子集 r
  • 更新时间 :
  • 英文 :


假设我有一个名为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
我想交换第B

列中的值,当它们被bc时,但不是在它们被ad时交换,条件是另一列C,即当C = 1时。所以目标数据帧是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

你可以试试chartr

chartr('bc', 'cb', df$B)
#[1] "a" "a" "c" "c" "b" "b" "d" "d"

那么,要以C == 1为条件,

df$B[df$C == 1] <- chartr('bc', 'cb', df$B[df$C == 1])
# 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

dplyr提供了一次替换多个值recode,如下所示。根据您问题中的新要求,我更新了下面的代码以提供所需的输出:

> 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
gsub("_", "", ifelse(df$B == "b", "_c", ifelse(df$B == "c", "_b", as.character(df$B))))
#[1] "a" "a" "c" "c" "b" "b" "d" "d"
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

最新更新