根据data.table中一列的值更改多列的值

时间:2018-09-25 04:52:15

标签: r data.table

假设我有一个数据表dt1

dt1 <- data.table(
names = c("A1", "XX", "A2", "XY", "A3", "XZ"),
   A1 = c( 0,    0,    0,    0,    0,    0), 
   A2 = c( 0,    0,    0,    0,    0,    0), 
   A3 = c( 0,    0,    0,    0,    0,    0)
)

我想要新的数据表,例如:

dt2 <- data.table(
names = c("A1", "XX", "A2", "XY", "A3", "XZ"),
   A1 = c( 1,    0,    0,    0,    0,    0), 
   A2 = c( 0,    0,    1,    0,    0,    0), 
   A3 = c( 0,    0,    0,    0,    1,    0)
)

即,如果列names的行值与某些列的名称相同,则该列的行值将更改为1

我可以通过以下代码实现这一目标:

dt1[names == "A1", "A1" := 1]
dt1[names == "A2", "A2" := 1]
dt1[names == "A3", "A3" := 1]

但是我想知道是否有更简单的方法可以做到这一点,尤其是当我要更改的列数很大时。

我尝试了以下几行,但它们不起作用:

cln <- c("A1", "A2", "A3")
dt1[names == (cln), (cln) := 1]

2 个答案:

答案 0 :(得分:1)

使用的有效for(...) set(...)组合:

for(j in names(dt1)[-1]) {
  set(dt1, dt1[, .I[names == j]], j, value = 1)
}

给出:

> dt1
   names A1 A2 A3
1:    A1  1  0  0
2:    XX  0  0  0
3:    A2  0  1  0
4:    XY  0  0  0
5:    A3  0  0  1
6:    XZ  0  0  0

您也可以使用names(dt1)[-1]代替setdiff(names(dt1), "names")

答案 1 :(得分:0)

您可以循环执行此操作。

for(i in colnames(dt1)[-1]) {
 dt1[,i] <- ifelse(dt1[,"names"] == i, 1, 0)
}