【问题标题】:If the previous and next rows are the same, add the full previous column如果上一行和下一行相同,则添加完整的上一列
【发布时间】:2019-07-04 06:15:23
【问题描述】:

我有一个data.table,想用Id作为不同的分组,上一行和下一行的秒数相差300多。

自动新增一列,以及上一列的内容,并可以根据两列的秒数差异判断需要添加几列

DT <-data.table(Id = c("A","A","A","A","A","B","B","B","B"),
                valueA = c(479117,479119,479117,479118,479118,479118,479118,479118,479121),
                valueB = c(209946,209948,209946,209953,209953,209953,209953,209951,209944),
                second = c(0,745,12,5,50,938,114,339,705))

测试数据框

     Id   valueA   valueB   second
 1   A    479117   209946     0
 2   A    478419   209948   745 
 3   A    479117   209946    12
 4   A    479118   209953     5
 5   A    479118   209953    50
 6   B    479118   209953   938
 7   B    479118   209953   114
 8   B    479118   209951   339
 9   B    479121   209944   705

我希望转换后的数据框看起来像这样

     Id   valueA   valueB   second
 1   A    479117   209946     0  #(original row 1)
#2   A    479117   209946   300  #(new row 2)
#3   A    479117   209946   300  #(new row 3)
 4   A    478419   209948   745  #(original row 2)
 5   A    479117   209946    12  #(original row 3)
 6   A    479118   209953     5
 7   A    479118   209953    50  #(original row 5)
 Because original row 5 and original row 6 Id is not the same, so don't compare
 8   B    479118   209953   938  #(original row 6)
 9   B    479118   209953   114
 10  B    479118   209951   339  #(original row 8)
#11  B    479118   209951   300  #(new row 11)
 12  B    479121   209944   705  #(original row 9)

因为原来的第1行和原来的第2行之间的秒数是745,所以新的第2行和新的第3行会复制上一行的内容。为什么要复制两次,因为 745/300=2.48(Round),取两次

原来的第 8 行和原来的第 9 行之间的秒数是 366 秒,所以新的第 11 行将复制前一行 (8) 的内容。为什么要复制一次,因为366/300=1.22,取一次(Round)

我的原始数据有两百万列

描述很复杂。不知道有没有什么办法?

谢谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    由于没有人想出一个聪明的解决方案,我会给你一个有点不雅但可能有效的方法:

    library(dplyr)
    library(purrr)
    
    grow_df <- function(x) {
      seconds <- DT %>% 
        filter(Id == x) %>% 
        pull(second)
    
      seconds2 <- c()
      for (i in seq(along = seconds)) {
        if (i == 1 || (i > 1 & seconds[i] - seconds[i - 1] <= 300)) {
          seconds2 <- c(seconds2, seconds[i])
        } else {
          for(j in 1:floor((seconds[i] - seconds[i - 1]) / 300)) {
            seconds2 <- c(seconds2, 300)
          }
          seconds2 <- c(seconds2, seconds[i])
        }
      }
      return(tibble(Id = x, second = seconds2))
    }
    
    map(DT$Id %>% unique, grow_df) %>% 
      bind_rows() %>% 
      left_join(DT, by = c("Id", "second")) %>% 
      fill(valueA, valueB) %>% 
      select(Id, valueA, valueB, second)
    

    注意:出于性能原因,您不应像我对seconds2 所做的那样“增长”向量。但它对示例有效。

    【讨论】:

    • 谢谢,它有效,我会尝试理解内容,它显示我的海量数据内存不足。
    • 如果能帮到你我很高兴。请accept my answer.
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多