【问题标题】:Replace a column in a datatable by another column using dynamic indexing使用动态索引将数据表中的列替换为另一列
【发布时间】:2019-09-18 18:19:15
【问题描述】:

类似于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

【问题讨论】:

  • 不确定。这是你想要的吗? DT[,3] &lt;- DT[,1] ?
  • 我认为这是DT[,1] &lt;- DT[,3]
  • 是的,是的,正确的。抱歉,我需要详细说明,因为我需要它更具动态性,因为它的多个列被多个其他列替换,基于两列的值。好的,我已经编辑了我的问题。

标签: r indexing dynamic replace data.table


【解决方案1】:

除了循环赋值语句之外,我认为没有任何优雅的方法可以实现这一点。所以基本上你需要使用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]]]]))

希望对大家有所帮助!

【讨论】:

  • 这样就产生了正确的data.table(期望的输出1),只不过输出的不是一个data.table,而是多个相同的data.table的列表(列表和个数一样大已完成的替换。)这会造成内存问题。
  • 是的,如果您将上述代码分配给 R 对象,那么您是正确的,但请记住使用 data.tables 您不需要将 lapply 分配给 R 对象。该循环应该至少与 for 循环一样具有内存效率,但在 R 中,lapply 循环执行效率更高。这就是为什么我说添加一个不可见的,这样你就看不到控制台的输出。如果您将代码分配给 R 对象,您将看不到控制台的输出,但您会将一个大列表保存到您的内存中。
猜你喜欢
  • 2021-05-13
  • 2021-11-19
  • 2013-10-05
  • 2021-01-24
  • 2021-06-11
  • 2016-11-27
  • 2019-03-23
  • 2018-11-06
  • 1970-01-01
相关资源
最近更新 更多