R 如果上一行和下一行相同,则添加完整的上一列

R 如果上一行和下一行相同,则添加完整的上一列,r,R,我有一个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),

我有一个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  #(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(轮),需要两次

原始行8和原始行9之间的秒数为366,因此新行11将复制前一行(8)的内容。为什么要复制一次,因为366/300=1.22,复制一次(轮)

我的原始数据有两百万列

描述非常复杂。我不知道有没有办法


谢谢。

因为还没有人想出一个聪明的解决方案,我会给你一个有点不公平但可能有效的方法:

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)
库(dplyr)
图书馆(purrr)
增长_df%
拉(秒)
秒2 1和秒[i]-秒[i-1]%
填充(值A、值B)%>%
选择(Id、值A、值B、秒)

注意:出于性能原因,您不应该像我在
seconds2
中那样“增长”向量。但是对于这个例子来说,它是有效的。

因为还没有人想出一个聪明的解决方案,我将给你一个有点不公平但可能有效的方法:

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)
库(dplyr)
图书馆(purrr)
增长_df%
拉(秒)
秒2 1和秒[i]-秒[i-1]%
填充(值A、值B)%>%
选择(Id、值A、值B、秒)

注意:出于性能原因,您不应该像我在
seconds2
中那样“增长”向量。但是它对这个例子很有效。

谢谢,它很有效,我会尽力理解它的内容,它显示出我的海量数据没有足够的内存。如果我能帮助你,我很高兴。请。谢谢,它工作,我会努力理解的内容,它显示我的巨大数据内存不足。我很高兴如果我能帮助你。请