扩展值以填充缺失值

extend a value to fill missing values

我想从第一个非缺失值开始填充缺失值并扩展它:

user   action
    1       NA
    1        2
    1       NA
    1       NA 
    1        3
    1       NA
    2       NA
    2       NA
    2        1
    2       NA

我想要的输出:

       user   action
        1        0
        1        2
        1        2
        1        2 
        1        3
        1        3
        2        0
        2        0
        2        1
        2        1

基本上,基于 user 我想填充 NA 值。它从 0 开始,当到达下一个值时,它扩展并替换 "NA"s 直到下一个值。它为每个用户继续。

使用ave处理分组,然后na.locf0结转最后一次出现的非NA,na.fill用0填充剩下的。

library(zoo)

transform(DF, action = na.fill(ave(action, user, FUN = na.locf0), 0))

给予:

   user action
1     1      0
2     1      2
3     1      2
4     1      2
5     1      3
6     1      3
7     2      0
8     2      0
9     2      1
10    2      1

备注

可重现形式的输入:

DF <- structure(list(user = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L
), action = c(NA, 2L, NA, NA, 3L, NA, NA, NA, 1L, NA)), 
class = "data.frame", row.names = c(NA, -10L))

使用 dplyrtidyrreplace 函数的解决方案。

library(dplyr)
library(tidyr)

dat2 <- dat %>%
  group_by(user) %>%
  fill(action) %>%
  ungroup() %>%
  replace(., is.na(.), 0)
dat2
# # A tibble: 10 x 2
#     user action
#    <int>  <dbl>
#  1     1      0
#  2     1      2
#  3     1      2
#  4     1      2
#  5     1      3
#  6     1      3
#  7     2      0
#  8     2      0
#  9     2      1
# 10     2      1

数据

dat <- read.table(text = "user   action
    1       NA
                  1        2
                  1       NA
                  1       NA 
                  1        3
                  1       NA
                  2       NA
                  2       NA
                  2        1
                  2       NA",
                  header = TRUE, stringsAsFactors = FALSE)

在 base R 中,您可以使用 ifelse 将值从 NA 转换为 0,然后使用 cummax 执行滚动扩展。 ave 将执行分组。

ave(ifelse(!is.na(dat$action), dat$action, 0), dat$user, FUN=cummax)
[1] 0 2 2 2 3 3 0 0 1 1

请注意,如果您的值不是单调递增,这将不起作用。