【问题标题】:Replace value in column by previous value having pattern用具有模式的先前值替换列中的值
【发布时间】:2023-02-03 09:30:10
【问题描述】:

假设我们将数据框 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

我需要用之前的 Start : ...... 替换列 a 的值,这表明它是完整的日期。

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

         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

数据x 始终具有Start : YMDD 的模式。

原始x 的行数超过10^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)

【问题讨论】:

  • Start 行之间的行数总是相同还是有所不同?
  • @RitchieSacramento 对于令人困惑的示例,我深表歉意。每天都不一样。

标签: r dplyr data.table data-manipulation


【解决方案1】:

这是一个 data.table 解决方案,使用 zoo::na.locf 来填充 NA 值。

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))

【讨论】:

  • 感谢您提供快速、高效的解决方案!祝你今天过得愉快 :)
猜你喜欢
  • 2023-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-01
  • 2019-10-02
  • 2019-03-24
  • 2018-12-05
相关资源
最近更新 更多