数据表:通过检查多行上的多列来创建新列

时间:2018-11-19 17:59:55

标签: r data.table

我目前有一个数据表,其中包含两列-'id'和'prevId'。我想通过从第一行开始,找到第二行,找到其“ id”等于第一行的“ prevId”,然后重复此过程直到“ prevId”为空白,来创建ID链。

然后,我想在链的末尾标识没有“ prevId”的“ id”,并创建一个新列,为每一行列出该发起者“ id”。

下面是我想要的输出的一个示例:

   id                  prevId originatorId createdAt
1: 11a                        11a          2018/1/12 
2: 11b                 11a    11a          2018/1/13
3: 11c                 11b    11a          2018/1/14
4: 12a                        12a          2018/1/12        
5: 12b                 12a    12a          2018/1/13

任何指导将不胜感激,谢谢!

编辑:

在测试某些建议的解决方案时,我注意到了一个警告。在某些情况下,某个元素的“ prevId”在任何其他元素中都不会被视为“ id”。如果要用来运行chinsoon的解决方案:

DT[, originatorId:=id[1L], by=cumsum(prevId==“”)]

这将导致此类元素将没有“ prevId”的最接近对等方列出为发起方,即使该对等方不属于id-prevId链。一个例子:

   id                  prevId originatorId createdAt
1: 10a                        10a          2018/1/12 
2: 11b                 11a    10a          2018/1/13
3: 11c                 11b    10a          2018/1/14

在这种情况下,“ 11a”应该是第二个和第三个元素的始发者,但是由于它不存在,因此“ 10a”代替了它。有没有可以解决此问题的调整?非常感谢。

2 个答案:

答案 0 :(得分:0)

我设法通过定义递归函数并将其应用于所有行来解决此问题。

image.Width - right

答案 1 :(得分:0)

现在可以通过两个递归步骤使用const scriptsWithKeywordCount = $('script:contains("zopim")').length; if (scriptsWithKeywordCount > 0) { // webpage contains keyword in javascript code } dplyr功能进行递归。

data.table

扩展了示例,以包含@Michael的注释。它具有很好的可扩展性,并且可以通过在管道中添加其他联接来调整递归步骤的数量。每次迭代后,它都会保存生成的联接数据表,因此可以轻松地执行匹配步骤。最后,将每个联接的结果组合起来,结果表应该可以很好地概述数据中的ID链。

dt <- structure(list(id = c("11a", "11b", "11c", "12a", "12b"), prevId = c(NA,  "11a", "11b", NA, "12a")), row.names = c(NA, -5L), class = c("data.table", "data.frame"))

data.table(left_join(x = dt
       , y = dt[,.(prevId)]
       , by = c("id" = "prevId")) %>% left_join(
                                            y = dt[,.(id,prevId)]
                                            , by = c("prevId" = "id")
       ))[, .(id, prevId, originatorId = ifelse(is.na(prevId.y), ifelse(is.na(prevId), id, prevId), prevId.y ))]

>  id   prevId  originatorId
1: 11a   <NA>          11a
2: 11b    11a          11a
3: 11c    11b          11a
4: 12a   <NA>          12a
5: 12b    12a          12a

生成的data.table看起来像这样:

library(dplyr)
left_join(x = dt
          , y = dt[,.(prevId)]
          , by = c("id" = "prevId")) %>% data.table(.) %>% { . ->> dt.join.1}   %>% left_join(x = .
                                                                                 , y = dt[,.(Second.id = id, Second.prevId = prevId)]
                                                                                , by = c("prevId" = "Second.id")) %>%  data.table(.) %>% { . ->> dt.join.2}


dt.join.final.data <- rbindlist(list(  dt.join.1
                                       , dt.join.2)
                                , fill = TRUE
                                , idcol = "id"
                                , use.names = TRUE)