使用 R 中的条件可互换地替换列值

Replacing column value interchangeably using a condition in R

在下面编码的 R 数据框中,如果“Dupl”列在行中有 8 个,我想将“Amount1”列与“Amount2”列值互换。

dt <- data.table(ID=c("A","A","B","B"),Amount1=c(100,200,300,400), Amount2=c(1500,1500,2400,2400),Dupl=c(1,8,1,0))

现在因为“Dupl”列有 8 个是第二行,所以我想在第二行中将“Amount1”更改为“Amount2”。

dt <- data.table(ID=c("A","A","B","B"),Amount1=c(100,1500,300,400), Amount2=c(1500,200,2400,2400),Dupl=c(1,8,1,0))

有什么建议吗?

base R中,这可以通过行列索引来完成,即对行使用逻辑条件,并在lhsrhs中反转列名16=]

dt[Dupl == 8, c("Amount1", "Amount2")] <- dt[Dupl == 8, c("Amount2", "Amount1")]

注意:Dupl == 8 之所以有效,是因为对象是 data.table。如果是单独一个data.frame,就用dt$Dupl == 8

-输出

> dt
   ID Amount1 Amount2 Dupl
1:  A     100    1500    1
2:  A    1500     200    8
3:  B     300    2400    1
4:  B     400    2400    0

data.table中的相同方法,即用逻辑条件指定i,以相反的顺序指定.SDcols,分配(:=)[的子集=35=] (.SD) 顺序正确

dt[Dupl == 8, c("Amount1", "Amount2") := .SD, .SDcols = c("Amount2", "Amount1")]

可以通过

进一步精简
cols <- c("Amount1", "Amount2")
dt[Dupl == 8, (cols) := .SD, .SDcols = rev(cols)][]

或者,

cols <- c("Amount1", "Amount2")
dt[Dupl == 8, rev(cols) := .SD, .SDcols = cols][]

两者都return

   ID Amount1 Amount2 Dupl
1:  A     100    1500    1
2:  A    1500     200    8
3:  B     300    2400    1
4:  B     400    2400    0

或者,避免 .SDcols 参数:

dt[Dupl == 8, `:=`(Amount1 = Amount2, Amount2 = Amount1)][]

我也尝试过 fifelse() 的方法,但是这些方法非常冗长,因为 fifelse() 只能处理向量值,例如

dt[, c("Amount1", "Amount2") := .(fifelse(Dupl == 8, Amount2, Amount1), 
                                  fifelse(Dupl == 8, Amount1, Amount2))][]

dt[, `:=`(Amount1 = fifelse(Dupl == 8, Amount2, Amount1), 
          Amount2 = fifelse(Dupl == 8, Amount1, Amount2))][]