使用动态索引将数据表中的列替换为另一列

时间:2019-04-30 06:19:05

标签: r indexing dynamic replace data.table

类似于Replace a value in a datatable by giving the column index, 我想只使用列索引将data.table中的列替换为同一data.table中的另一列。 (是的,尽管通常这不是一个好习惯。在我看来,这是唯一的方法)

DT <- data.table(A=1:5, B=6:10, C=10:14)

我想要

DT[, A:=C] 

但不使用A和C。仅使用索引号1和3。


编辑:需要详细说明我的用例。我有多个列,需要用其他多个列替换。替换用data.table中的两列表示。

    DT <- data.table(A=1:5
                   , B=6:10
                   , C=10:14
                   , D=15:19
                   , E=20:24
                   , F=25:29
                   , G=c(1,2,NA,NA,NA)
                   , H=c(3,4,NA,NA,NA))

> DT
   A  B  C  D  E  F  G  H
1: 1  6 10 15 20 25  1  3  # --> column 1 (A) should be replaced by column 3 (C)
2: 2  7 11 16 21 26  2  4  # --> column 2 (B) should be replaced by column 4 (D)
3: 3  8 12 17 22 27 NA NA
4: 4  9 13 18 23 28 NA NA
5: 5 10 14 19 24 29 NA NA

G列指示需要替换的列。 H列指示将替换G列中指示的列的列。处理具有几千列的data.table。而且我知道H和G列的名称,因此它们不必是动态的。

所需的输出:

> desired_output1:
    A  B  C  D  E  F  G  H
1: 10 15 10 15 20 25  1  3   #all of column A was replaced by column C
2: 11 16 11 16 21 26  2  4   #all of column B was replaced by column D
3: 12 17 12 17 22 27 NA NA
4: 13 18 13 18 23 28 NA NA
5: 14 19 14 19 24 29 NA NA

> desired_output2:
    A  B  C  D  E  F  G  H
1: 10  6 10 15 20 25  1  3   # col A for this row was replaced by col C
2:  2 16 11 16 21 26  2  4   # col B for this row was replaced by col D
3:  3  8 12 17 22 27  1  2
4:  4  9 13 18 23 28 NA NA
5:  5 10 14 19 24 29 NA NA

1 个答案:

答案 0 :(得分:0)

好吧,我认为除了循环执行assign语句外,没有其他任何优雅的方法可以做到这一点。因此,基本上,您将需要使用DT[["G"]][i]来替换要使用的ith列,然后使用列表表示法来使用DT[["H"]][i]来替换列。在data.table中,您可以参考要用数字替换的列,但是要获取替换值,您将需要使用DT[[DT[["H"]][i]]],对于i=1,该值将是DT[[3]]。将所有内容放到一个lapply循环中将为您提供以下内容:

lapply(seq_along(na.omit(DT[["G"]])),function(i) DT[,DT[["G"]][i]:=DT[[DT[["H"]][i]]]])

由于第G列和第H列均包含值或均为NA,因此您可以在lapply中选择G的索引中选择一个。但是,请确保NA值位于列的末尾或seq_along在执行循环时会给您错误的索引。根据您的描述,我认为情况确实如此。

由于您实际上并不关心lapply产生的列表,而只是将其用作更有效的for循环,因此可以抑制向控制台的输出(如果您这样做,可能会很烦人。可以更改成千上万的列),如果需要,可以将以上内容用不可见的文字括起来:

invisible(lapply(seq_along(na.omit(DT[["G"]])),function(i) DT[,DT[["G"]][i]:=DT[[DT[["H"]][i]]]]))

希望这对您有所帮助!