【问题标题】:Change values of multiple columns based on the value of one column in data.table根据data.table中一列的值更改多列的值
【发布时间】:2018-09-25 04:52:14
【问题描述】:

假设我有一个数据表,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]

【问题讨论】:

    标签: r data.table


    【解决方案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
    

    您也可以使用setdiff(names(dt1), "names"),而不是names(dt1)[-1]

    【讨论】:

    • 对不起,我的错。我已删除评论。
    • @LikanZhan 没问题
    【解决方案2】:

    你可以用循环来做到这一点。

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

    【讨论】:

    • colnames(dt1)[-"names"] 不起作用....(它不是有效的 R 语法)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    相关资源
    最近更新 更多