【问题标题】:How to create a new column in data.table based on values of other columns如何根据其他列的值在 data.table 中创建新列
【发布时间】:2019-10-18 15:12:02
【问题描述】:

我有以下data.table格式的数据结构:

ID  Cycle  Cycle_Day Cycle_Date  Positive_Test_Date
1   1      1         3/28/2019   NA
1   1      2         3/29/2019   NA
1   1      3         3/30/2019   NA
1   1      NA        NA          3/29/2019
1   2      1         4/23/2019   NA 
1   2      2         4/24/2019   NA
1   2      3         4/25/2019   NA
1   2      NA        NA          4/25/2019
2   1      1         3/18/2019   NA
2   1      2         3/19/2019   NA
2   1      3         3/20/2019   NA
2   1      NA        NA          3/18/2019
2   2      1         4/23/2019   NA 
2   2      2         4/24/2019   NA
2   2      3         4/25/2019   NA
2   2      NA        NA          4/24/2019

我想创建一个新列“LH_Date”,它将为每个 ID 和每个周期复制事件 Cycle_Date 和 Positive_Test_Date 匹配中的日期。否则值为 NA。它应该是这样的:

ID  Cycle  Cycle_Day Cycle_Date  Positive_Test_Date LH_Date
1   1      1         3/28/2019   NA                 NA 
1   1      2         3/29/2019   NA                 3/29/2019
1   1      3         3/30/2019   NA                 NA
1   1      NA        NA          3/29/2019          NA
1   2      1         4/23/2019   NA                 NA
1   2      2         4/24/2019   NA                 NA
1   2      3         4/25/2019   NA                 4/25/2019
1   2      NA        NA          4/25/2019          NA
2   1      1         3/18/2019   NA                 3/18/2019
2   1      2         3/19/2019   NA                 NA
2   1      3         3/20/2019   NA                 NA 
2   1      NA        NA          3/18/2019          NA
2   2      1         4/23/2019   NA                 NA
2   2      2         4/24/2019   NA                 4/24/2019
2   2      3         4/25/2019   NA                 NA
2   2      NA        NA          4/24/2019          NA

【问题讨论】:

  • 格式是否正确?很难说...
  • 您能否添加第一行的 dput(dt) 输出,比如 20 行,以便我们重现您的数据?
  • 抱歉,不知道该怎么做。如果你告诉我怎么做,很高兴。

标签: r data.table


【解决方案1】:

另一种选择是使用索引来查找符合条件的行并仅更新这些行:

#for each group of ID and Cycle, 
#find the row indices where Cycle_Date equals the last Positive_Test_Date 
idxDT <- DT[, .I[Cycle_Date==Positive_Test_Date[.N]], .(ID, Cycle)]

#for those row indices, set the LH_Date to be Cycle_Date 
#(NA rows or excluded rows defaults to NA by design in data.table)
DT[idxDT$V1, LH_Date := Cycle_Date]

idxDT 看起来像这样,idxDT$V1 提取列 V1

   ID Cycle V1
1:  1     1  2
2:  1     1 NA
3:  1     2  7
4:  1     2 NA
5:  2     1  9
6:  2     1 NA
7:  2     2 14
8:  2     2 NA

.I 包含 data.table 中的行索引。来自?.I

.I 是一个等于 seq_len(nrow(x)) 的整数向量。分组时,它为组中的每个项目保留其在 x 中的行位置。这对 j 中的子集很有用;例如DT[, .I[which.max(somecol)], by=grp].

输出:

    ID Cycle Cycle_Day Cycle_Date Positive_Test_Date   LH_Date
 1:  1     1         1  3/28/2019               <NA>      <NA>
 2:  1     1         2  3/29/2019               <NA> 3/29/2019
 3:  1     1         3  3/30/2019               <NA>      <NA>
 4:  1     1        NA       <NA>          3/29/2019      <NA>
 5:  1     2         1  4/23/2019               <NA>      <NA>
 6:  1     2         2  4/24/2019               <NA>      <NA>
 7:  1     2         3  4/25/2019               <NA> 4/25/2019
 8:  1     2        NA       <NA>          4/25/2019      <NA>
 9:  2     1         1  3/18/2019               <NA> 3/18/2019
10:  2     1         2  3/19/2019               <NA>      <NA>
11:  2     1         3  3/20/2019               <NA>      <NA>
12:  2     1        NA       <NA>          3/18/2019      <NA>
13:  2     2         1  4/23/2019               <NA>      <NA>
14:  2     2         2  4/24/2019               <NA> 4/24/2019
15:  2     2         3  4/25/2019               <NA>      <NA>
16:  2     2        NA       <NA>          4/24/2019      <NA>

数据:

library(data.table)
DT <- fread("ID  Cycle  Cycle_Day Cycle_Date  Positive_Test_Date
1   1      1         3/28/2019   NA
1   1      2         3/29/2019   NA
1   1      3         3/30/2019   NA
1   1      NA        NA          3/29/2019
1   2      1         4/23/2019   NA 
1   2      2         4/24/2019   NA
1   2      3         4/25/2019   NA
1   2      NA        NA          4/25/2019
2   1      1         3/18/2019   NA
2   1      2         3/19/2019   NA
2   1      3         3/20/2019   NA
2   1      NA        NA          3/18/2019
2   2      1         4/23/2019   NA 
2   2      2         4/24/2019   NA
2   2      3         4/25/2019   NA
2   2      NA        NA          4/24/2019")

【讨论】:

  • 非常感谢。我只熟悉 data.table 的 i, j by 格式。如果您不介意我有几个问题: 1. 双括号格式 [[ ]] 在这种特殊情况下有什么作用?在 DT[DT[, ]] 中,如果逗号之前的部分引用 i 并且您正在过滤符合条件的行,为什么它是空的? 3. .I 代表什么? 4. 什么是 $V1?如果我的问题令人困惑,请随时提供您自己的解释,我会弄清楚的。再次感谢!
  • 嗨@user12239114,我已经添加了解释。希望它现在清楚了。
  • 你好 chinsoon12。是的,这是有道理的——非常感谢您的解释。我明白了!
【解决方案2】:

假设您的数据位于名为 DTdata.table 中:

第一个过滤器DT,其中Positive_Test_Date 不是NA(因为它们对于创建新列没有用处)

ptd_notna <- DT[!is.na(Positive_Test_Date)]

然后将您的原始表与IDCycle 上的这个表连接起来,并创建一个新列idx,它是一个布尔值,表示表XCycle_Date 是否相等到每个组的 table iPositive_Test_Date。将连接视为X[Y],因此您指的是 Xx.colname 的列以及 Yi.colname 的列(因为 Y Xi 部分)。

DT[ptd_notna, 
   idx := x.Cycle_Date == i.Positive_Test_Date, 
   on = .(ID, Cycle)]

现在您可以使用这个新列idx 来过滤您的表,并将新列LH_Date 分配为等于Cycle_Date。请注意如何在 i 中使用布尔列,您使用了括号。

DT[(idx), LH_Date := Cycle_Date]

如果您认为不需要,请删除 idx

DT[, idx := NULL]

【讨论】:

  • 如果您有时间解释您的逻辑(或将我指向 data.table 文档中的部分),我将不胜感激。
  • 非常感谢。这很有帮助。我一步一步完成了这一步,你对每一步的解释都很有道理。
猜你喜欢
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2023-03-17
  • 2020-04-12
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多