data.table(R)中的ifelse行为

时间:2015-01-29 19:50:26

标签: r data.table

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

为实现这一目标,我得到了以下内容:

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

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

所以,quality_1主要是我想要的。如果期间X为'low'且期间X-1为'high',我们会看到重新分类为'high',并且quality的所有内容大部分都保持不变。但是,当quality_lag为NA时,'low'会在NA中重新归类为quality_1。这不是'high''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

有关导致此问题的任何想法?

2 个答案:

答案 0 :(得分:6)

对于初学者来说,Development version on GitHub已经有一个名为shift的有效滞后函数,它可以用作滞后或导致(并且还有一些额外的功能,请参阅?shift)。< / p>

还要看看here,因为v> = 1.9.5中存在许多其他新功能

所以在v&gt; = 1.9.5下我们可以简单地做

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

即使在v&lt; 1.9.5您可以使用.N而不是以下列方式创建此功能

foo[, quality_lag2 := c(NA, quality[-.N]), by = group]

关于您的第二个问题,我建议一起避免ifelse所有问题here

一种可能的替代方案是,只需使用

中的简单索引
foo[, quality_1 := quality][quality == 'low' & quality_lag == 'high', quality_1 := "high"]

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

答案 1 :(得分:-3)

您的问题是ifelse(NA, 1, 2) == NA,当您执行NA == 'low'时,结果为NA。一个简单的解决方法是将NA表示为滞后函数中的字符串。这是您的代码的工作版本:

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