R-如何在数据帧中的两个对应ID之间填充NA

R-如何在数据帧中的两个对应ID之间填充NA,r,data-munging,R,Data Munging,我正在尝试将下面的数据集转换为第二个数据集。基本上,我试着用那个ID填充每个ID之间的NA 每个ID对应两个时间戳,我加入了一个更大的日期时间列。出于可复制性的目的,在日期和时间列之间执行sql连接的计算成本太高,甚至需要获取原始数据集,在每个id之间创建时间戳,然后将其连接起来。我有太多的id来执行此操作。我已经成功地完成了这两种方法,但对于我拥有的数据量来说,这需要太多的时间。我希望用这个数据集来处理数据。这似乎是件很简单的事,但它真的把我难住了。任何帮助都将不胜感激 当前数据集:

我正在尝试将下面的数据集转换为第二个数据集。基本上,我试着用那个ID填充每个ID之间的NA

每个ID对应两个时间戳,我加入了一个更大的日期时间列。出于可复制性的目的,在日期和时间列之间执行sql连接的计算成本太高,甚至需要获取原始数据集,在每个id之间创建时间戳,然后将其连接起来。我有太多的id来执行此操作。我已经成功地完成了这两种方法,但对于我拥有的数据量来说,这需要太多的时间。我希望用这个数据集来处理数据。这似乎是件很简单的事,但它真的把我难住了。任何帮助都将不胜感激

当前数据集:

             date_time     id
                <dttm>  <dbl>
 1 2017-01-30 08:00:00     NA
 2 2017-01-30 08:00:01     NA
 3 2017-01-30 08:00:02     1
 4 2017-01-30 08:00:03     NA
 5 2017-01-30 08:00:04     NA
 6 2017-01-30 08:00:05     NA
 7 2017-01-30 08:00:06     NA
 8 2017-01-30 08:00:07     1
 9 2017-01-30 08:00:08     NA
10 2017-01-30 08:00:09     NA
11 2017-01-30 08:00:10     2
12 2017-01-30 08:00:11     NA
13 2017-01-30 08:00:12     NA
14 2017-01-30 08:00:13     NA
15 2017-01-30 08:00:14     2
16 2017-01-30 08:00:15     NA
17 2017-01-30 08:00:16     3
18 2017-01-30 08:00:17     NA
19 2017-01-30 08:00:18     3
20 2017-01-30 08:00:19     NA

一种解决方案是使用tidyr的填充函数。方法很简单。首先创建两列,分别对应上一个和下一个值。使用“填充”填充两列中缺少的值

现在,对于在“上一个值”和“下一个值”中具有相同值的行,应使用“上一个值”更新该值,这意味着缺少的值介于相同的数字之间

df <-  read.table(text = "sl date_time, value
1 '2017-01-30 08:00:00'     NA
2 '2017-01-30 08:00:01'     NA
3 '2017-01-30 08:00:02'     1
4 '2017-01-30 08:00:03'     NA
5 '2017-01-30 08:00:04'     NA
6 '2017-01-30 08:00:05'     NA
7 '2017-01-30 08:00:06'     NA
8 '2017-01-30 08:00:07'     1
9 '2017-01-30 08:00:08'     NA
10 '2017-01-30 08:00:09'     NA
11 '2017-01-30 08:00:10'     2
12 '2017-01-30 08:00:11'     NA
13 '2017-01-30 08:00:12'     NA
14 '2017-01-30 08:00:13'     NA
15 '2017-01-30 08:00:14'     2
16 '2017-01-30 08:00:15'     NA
17 '2017-01-30 08:00:16'     3
18 '2017-01-30 08:00:17'     NA
19 '2017-01-30 08:00:18'     3
20 '2017-01-30 08:00:19'     NA", header = T, stringsAsFactor = F)

#use fill to find missing values
df %>%
  mutate(prev_val = (value), next_val = (value)) %>%
  fill(prev_val, .direction = "down") %>%
  fill(next_val, .direction = "up") %>%
  mutate(value = ifelse(prev_val == next_val, prev_val, value )) %>%
  select(-prev_val, -next_val)

Result:
   sl          date_time. value
1   1 2017-01-30 08:00:00    NA
2   2 2017-01-30 08:00:01    NA
3   3 2017-01-30 08:00:02     1
4   4 2017-01-30 08:00:03     1
5   5 2017-01-30 08:00:04     1
6   6 2017-01-30 08:00:05     1
7   7 2017-01-30 08:00:06     1
8   8 2017-01-30 08:00:07     1
9   9 2017-01-30 08:00:08    NA
10 10 2017-01-30 08:00:09    NA
11 11 2017-01-30 08:00:10     2
12 12 2017-01-30 08:00:11     2
13 13 2017-01-30 08:00:12     2
14 14 2017-01-30 08:00:13     2
15 15 2017-01-30 08:00:14     2
16 16 2017-01-30 08:00:15    NA
17 17 2017-01-30 08:00:16     3
18 18 2017-01-30 08:00:17     3
19 19 2017-01-30 08:00:18     3
20 20 2017-01-30 08:00:19    NA
这是一个基本的R选项。我们使用“trx_id”分割数据集的行序列,其中一个OP显示为输入数据,获取序列seq,将其堆叠到两列数据集,并基于“value”将“trx_id”分配给“d1”的“ind”列作为“d1”的索引

d1 <- stack(lapply(split(seq_len(nrow(df1)), df1$trx_id), function(x) seq(x[1], x[2])))
df1$trx_id[d1$values] <- d1$ind
df1$trx_id
#[1] NA NA  1  1  1  1  1  1 NA NA  2  2  2  2  2 NA  3  3  3 NA

非tidyr方法,其中x是您的id列:

x <- c(NA,NA, 1,NA,NA,1, NA, NA, 2, NA, NA,2, NA, 3,NA, NA,3,NA)

timestamps <- paste(unique(x)[!is.na(unique(x))], collapse = "|")

timestamps <- grep(timestamps, x)
timestamps <- matrix(timestamps, ncol = 2, byrow=TRUE)

xmatrix <- apply(timestamps, MARGIN = 1, FUN = function(i) {
  y <- x[i[1]:i[2]]
  y[is.na(y)] <- x[i][1]
  x[i[1]:i[2]] <- y 
  return(x)
})

(x <- apply(xmatrix, 1,FUN = function(z) {

  ifelse(all(is.na(z)), NA, max(z, na.rm=TRUE))
  }))

##  [1] NA NA  1  1  1  1 NA NA  2  2  2  2 NA  3  3  3  3 NA

HTH

您是否可以使用dput以便我们可以复制示例数据帧?请使用package zoo中的函数na.locf。可能重复的@Pdubbs I添加了dput的输出。我不熟悉包含可复制的示例,所以请告诉我我所做的是否正确。@RuiBarradas我尝试了na.locf,但它会在ID之后填充na,因此如果有c3,na,na,3,na,na,4,它会将其转换为c3,3,3,3,3,4,这是我不想要的。我希望数据是c3,3,3,3,NA,NA,4。这非常有效。非常感谢。在我的完整数据集上尝试此操作时,我遇到了一个错误。它说seq.defaultx[1],x[2]中的错误:“to”必须是一个有限数。我正在努力解决这个问题,但在我给出的示例代码中它确实有效。@jstauss这很有趣。你能检查一下splitseq_lennrowdf1,df1$trx_id的输出吗?谢谢。试着把它放在整洁的房间里,但效果很好。
d1 <- stack(lapply(split(seq_len(nrow(df1)), df1$trx_id), function(x) seq(x[1], x[2])))
df1$trx_id[d1$values] <- d1$ind
df1$trx_id
#[1] NA NA  1  1  1  1  1  1 NA NA  2  2  2  2  2 NA  3  3  3 NA
x <- c(NA,NA, 1,NA,NA,1, NA, NA, 2, NA, NA,2, NA, 3,NA, NA,3,NA)

timestamps <- paste(unique(x)[!is.na(unique(x))], collapse = "|")

timestamps <- grep(timestamps, x)
timestamps <- matrix(timestamps, ncol = 2, byrow=TRUE)

xmatrix <- apply(timestamps, MARGIN = 1, FUN = function(i) {
  y <- x[i[1]:i[2]]
  y[is.na(y)] <- x[i][1]
  x[i[1]:i[2]] <- y 
  return(x)
})

(x <- apply(xmatrix, 1,FUN = function(z) {

  ifelse(all(is.na(z)), NA, max(z, na.rm=TRUE))
  }))

##  [1] NA NA  1  1  1  1 NA NA  2  2  2  2 NA  3  3  3  3 NA