data.table(R)中的ifelse行为

tha*_*one 5 r data.table

我有一个data.table充满了一些消费产品.我已经创造了一些区别的产品作为'low','high'或'unknown'质量.数据是时间序列,我有兴趣平滑数据中的一些季节性.如果产品的原始分类(由我用来确定质量的算法生成的分类)是'low'X期的质量,但其原始分类是'high'X-1期间的质量,我将该产品重新分类'high'为期间X的质量.过程是在某种产品组的区别内完成的.

要做到这一点,我有类似以下内容:

require(data.table)

# lag takes a column and lags it by one period,
# padding with NA

lag <- function(var) {
    lagged <- c(NA, 
                var[1:(length(var)-1)])
    return(lagged)
}

set.seed(120)

foo <- data.table(group = c('A', rep(c('B', 'C', 'D'), 5)),
                  period = c(1:16),
                  quality = c('unknown', sample(c('high', 'low', 'unknown'), 15, replace = TRUE)))

foo[, quality_lag := lag(quality), by = group]

foo[, quality_1 := ifelse(quality == 'low' & quality_lag == 'high',
                          'high',
                          quality)]
Run Code Online (Sandbox Code Playgroud)

看看foo:

    group period quality quality_lag quality_1
 1:     A      1 unknown          NA   unknown
 2:     B      2     low          NA        NA
 3:     C      3    high          NA      high
 4:     D      4     low          NA        NA
 5:     B      5 unknown         low   unknown
 6:     C      6    high        high      high
 7:     D      7     low         low       low
 8:     B      8 unknown     unknown   unknown
 9:     C      9    high        high      high
10:     D     10 unknown         low   unknown
11:     B     11 unknown     unknown   unknown
12:     C     12     low        high      high
13:     D     13 unknown     unknown   unknown
14:     B     14    high     unknown      high
15:     C     15    high         low      high
16:     D     16 unknown     unknown   unknown
Run Code Online (Sandbox Code Playgroud)

所以,quality_1主要是我想要的.如果期间X是'low',期间X-1是'high',我们看到重新分类'high'发生,一切都保持完整quality.但是,如果quality_lag是NA,'low'被重新分类为NA在quality_1.这不是'high'or 的问题'unknown'.

也就是说,前四行foo 应该如下所示:

   group period quality quality_lag quality_1
 1:     A      1 unknown          NA   unknown
 2:     B      2     low          NA       low
 3:     C      3    high          NA      high
 4:     D      4     low          NA       low
Run Code Online (Sandbox Code Playgroud)

对这是什么造成的任何想法?

Dav*_*urg 6

对于初学者来说,GitHub上的开发版本已经有一个有效的滞后函数shift,可以用作滞后或导致(并且还有一些额外的功能,请参阅参考资料?shift).

另请看一下,因为v> = 1.9.5中存在许多其他新功能

所以在v> = 1.9.5下我们可以做到

foo[, quality_lag := shift(quality), by = group]
Run Code Online (Sandbox Code Playgroud)

虽然即使在v <1.9.5下,您也可以使用.N以下方式创建此功能

foo[, quality_lag2 := c(NA, quality[-.N]), by = group]
Run Code Online (Sandbox Code Playgroud)

关于你的第二个问题,我会建议避免ifelse一起为指定的原因有很多在这里

一种可能的替代方案是,只需使用简单的索引

foo[, quality_1 := quality][quality == 'low' & quality_lag == 'high', quality_1 := "high"]
Run Code Online (Sandbox Code Playgroud)

这个解决方案有两个开销,调用[.data.table两次,但它仍然比ifelse解决方案更有效/更安全.