将列中的值替换为具有模式的前值

Replace value in column by previous value having pattern

提问人:Park 提问时间:2/3/2023 最后编辑:Park 更新时间:2/3/2023 访问量:43

问:

假设我们将数据框定义为x

x <- data.frame(a = c('Start : 20220101', '1', '1', '1', 'Start : 20220102', '2', '2', 'Start : 20220103', '3', '3'),
           b = c(NA, 200, 200, 200, NA, 200, 200, NA, 200, 200),
           c = c(NA, 1, 3, 5, NA, 2, 4, NA, 3, 5))

                  a   b  c
1  Start : 20220101  NA NA
2                 1 200  1
3                 1 200  3
4                 1 200  5
5  Start : 20220102  NA NA
6                 2 200  2
7                 2 200  4
8  Start : 20220103  NA NA
9                 3 200  3
10                3 200  5

我需要将列的值替换为以前的 ,这表明它是完整的日期。aStart : ......

我想要的输出可能会使问题更清楚。

         a     b     c
1 20220101   200     1
2 20220101   200     3
3 20220101   200     5
4 20220102   200     2
5 20220102   200     4
6 20220103   200     3
7 20220103   200     5

数据总是有 patern with 和 follow。xStart : YMDD

原始的行数不止行,所以我认为它需要非常高效。x10^8

任何帮助将不胜感激。

我尝试的是

library(dplyr)
library(data.table)
library(readr)

x %>%
  mutate(d = floor((rleid(a)+1)/2))  %>%
  group_by(d) %>%
  mutate(a = first(parse_number(a))) %>%
  na.omit() %>%
  ungroup %>%
  select(-d)
r dplyr data.table 数据操作

评论

0赞 Ritchie Sacramento 2/3/2023
行与行之间的行数总是相同还是不同?Start
0赞 Park 2/3/2023
@RitchieSacramento 对于令人困惑的例子,我深表歉意。每天都不一样。

答:

1赞 Ronak Shah 2/3/2023 #1

这是一个填充值的解决方案。data.tablezoo::na.locfNA

library(data.table)

setDT(x)
#Change all the a values to NA except the ones that start with "Start"
x[, a := replace(a, !grepl('^Start', a), NA)]
#Remove "Start" from a so only the date remains. 
x[, a := sub('Start\\s*:\\s*', '', a)]
#Replace NA with latest non-NA values.
zoo::na.locf(x)

#          a   b c
#1: 20220101 200 1
#2: 20220101 200 3
#3: 20220102 200 3
#4: 20220102 200 2
#5: 20220102 200 4
#6: 20220103 200 4
#7: 20220103 200 3

同样的解决方案是——tidyverse

library(dplyr)
library(tidyr)

x %>%
  mutate(a = replace(a, !grepl('^Start', a), NA)) %>%
  fill(everything(), .direction = "downup") %>%
  mutate(a = sub('Start\\s*:\\s*', '', a))

评论

0赞 Park 2/3/2023
感谢您提供快速、高效的解决方案!祝你有美好的一天:)