r - 按组有条件NA填充

标签 r dplyr data.table plyr na

编辑
该问题最初是为data.table询问的。任何包装的解决方案都会很有趣。

我对一个更普遍的问题的特定变化有些困惑。我有与data.table一起使用的面板数据,我想使用group。data.table的功能来填写一些缺少的值。不幸的是,它们不是数字的,因此我不能简单地插值,而只能根据条件进行填充。是否有可能在data.tables中执行一种条件na.locf?

从本质上讲,我只想在NA之后填写下一个观察值是先前的观察值,尽管更普遍的问题是如何有条件地填写NA。

例如,在以下数据中,我想按每个id组填写associatedid变量。因此,id==1year==2003将作为ABC123填写,因为它在NA之前和之后的值,但对于相同的id不是2000。 id== 2不会更改,因为下一个值与NA之前的值不同。 id==3将在2003和2004年填写。

mydf <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), year = c(2000L, 2001L, 2002L, 2003L, 2004L, 2005L, 2000L, 2001L, 2002L, 2003L, 2004L, 2005L, 2000L, 2001L, 2002L, 2003L, 2004L, 2005L), associatedid = structure(c(NA, 1L, 1L, NA, 1L, 1L, NA, 1L, 1L, NA, 2L, 2L, NA, 1L, 1L, NA, NA, 1L), .Label = c("ABC123", "DEF456"), class = "factor")), class = "data.frame", row.names = c(NA, -18L))

mydf
#>    id year associatedid
#> 1   1 2000         <NA>
#> 2   1 2001       ABC123
#> 3   1 2002       ABC123
#> 4   1 2003         <NA>
#> 5   1 2004       ABC123
#> 6   1 2005       ABC123
#> 7   2 2000         <NA>
#> 8   2 2001       ABC123
#> 9   2 2002       ABC123
#> 10  2 2003         <NA>
#> 11  2 2004       DEF456
#> 12  2 2005       DEF456
#> 13  3 2000         <NA>
#> 14  3 2001       ABC123
#> 15  3 2002       ABC123
#> 16  3 2003         <NA>
#> 17  3 2004         <NA>
#> 18  3 2005       ABC123

dt = data.table(mydf, key = c("id"))

期望的输出

#>    id year associatedid
#> 1   1 2000         <NA>
#> 2   1 2001       ABC123
#> 3   1 2002       ABC123
#> 4   1 2003       ABC123
#> 5   1 2004       ABC123
#> 6   1 2005       ABC123
#> 7   2 2000         <NA>
#> 8   2 2001       ABC123
#> 9   2 2002       ABC123
#> 10  2 2003         <NA>
#> 11  2 2004       DEF456
#> 12  2 2005       DEF456
#> 13  3 2000         <NA>
#> 14  3 2001       ABC123
#> 15  3 2002       ABC123
#> 16  3 2003       ABC123
#> 17  3 2004       ABC123
#> 18  3 2005       ABC123

最佳答案

这就是编写修改的na.locf函数的全部内容。之后,您可以将其插入到data.table中,就像其他任何函数一样。

new.locf <- function(x){
  # might want to think about the end of this loop
  # this works here but you might need to add another case
  # if there are NA's as the last value.
  #
  # anyway, loop through observations in a vector, x.
  for(i in 2:(length(x)-1)){
    nextval = i
    # find the next, non-NA value
    # again, not tested but might break if there isn't one?
    while(nextval <= length(x)-1 & is.na(x[nextval])){
      nextval = nextval + 1
    }
    # if the current value is not NA, great!
    if(!is.na(x[i])){
      x[i] <- x[i]
    }else{
      # if the current value is NA, and the last value is a value
      # (should given the nature of this loop), and
      # the next value, as calculated above, is the same as the last
      # value, then give us that value. 
      if(is.na(x[i]) & !is.na(x[i-1]) & x[i-1] == x[nextval]){
        x[i] <- x[nextval]
      }else{
        # finally, return NA if neither of these conditions hold
        x[i] <- NA
      }
    }
  }
  # return the new vector
  return(x) 
}

一旦有了该功能,便可以照常使用data.table:
dt2 <- dt[,list(year = year,
                # when I read your data in, associatedid read as factor
                associatedid = new.locf(as.character(associatedid))
                ),
          by = "id"
          ]

这将返回:
> dt2
    id year associatedid
 1:  1 2000           NA
 2:  1 2001       ABC123
 3:  1 2002       ABC123
 4:  1 2003       ABC123
 5:  1 2004       ABC123
 6:  1 2005       ABC123
 7:  2 2000           NA
 8:  2 2001       ABC123
 9:  2 2002       ABC123
10:  2 2003           NA
11:  2 2004       DEF456
12:  2 2005       DEF456
13:  3 2000           NA
14:  3 2001       ABC123
15:  3 2002       ABC123
16:  3 2003       ABC123
17:  3 2004       ABC123
18:  3 2005       ABC123

据我所知,这正是您在寻找的东西。

我在new.locf定义中提供了一些套期保值功能,因此您可能仍需要考虑一下,但这应该可以帮助您入门。

关于r - 按组有条件NA填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27368770/

相关文章:

r - 带有线到标签的自定义 Axis

r - 使用存储的凭据通过 dplyr 连接到 MySQL 数据库

r - 如何在R中过滤数据帧每列中的NA

r 如何将 mapply 与数据表一起使用

r - 根据列索引向量选择 data.table 值

rlang - 创建带有 curly curly 的字符串以便稍后评估

重复数值向量

R:如何从数据框中提取列表?

r - 使用 rollends 滚动连接参数的 data.table 混淆

r - 如何在没有坐标极的情况下制作堆积圆图