使用 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
中,这可以通过行列索引来完成,即对行使用逻辑条件,并在lhs
和rhs
中反转列名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))][]
在下面编码的 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
中,这可以通过行列索引来完成,即对行使用逻辑条件,并在lhs
和rhs
中反转列名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))][]