2015-01-29 4 views
5

일부 소비자 제품으로 가득 찬 data.table이 있습니다. 제품에 대한 몇 가지 차이점을 'low', 'high' 또는 'unknown' 품질로 작성했습니다. 데이터는 시계열이며 데이터의 일부 계절성을 부드럽게하는 데 관심이 있습니다. 제품의 원시 분류 (품질을 결정하는 데 사용한 알고리즘에 의해 분류 된 분류)는 기간 X의 품질이 'low'이지만 원시 분류가 기간 X-1의 품질이 'high' 인 경우 해당 기간을 'high' 품질로 재 분류합니다. X.이 프로세스는 일종의 제품 그룹 구분 내에서 수행됩니다. foo에서data.table (R) 내의 Ifelse 동작

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

을 살펴보면 :

이를 위해

는, 나는 다음과 같은 일을 가지고

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'quality_1NA으로 재 분류됩니다. 'high' 또는 'unknown'의 문제는 아닙니다.

즉, foo첫 4 행은 다음과 같아야합니다 :이 원인이 무엇에

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 

어떤 생각?

+7

처음에는 휠을 다시 만들 필요가 없습니다. 'data.table' v> = 1.9.5는 이미'shift' 라 불리는'지연 (lag) '함수를 가지고 있으므로'foo [, quality_lag : = shift (quality), by = group]' –

+6

두번째로' ifelse'는 진정으로 awefull 함수이며 나는 항상 그것을 피하려고합니다. 나의 충고는'foo [, quality_1 : = 품질] [quality == 'low'& quality_lag == 'high', quality_1 : = "high"]' –

+1

과 같은 것을 할 것입니다. @DavidArenburg의 요점은 죽었습니다. 또한 ifelse에 대한 자세한 정보는 http://stackoverflow.com/q/16275149/1492421을 참조하십시오 –

답변

6

에서, Development version on GitHub 이미 지연이나 납으로 모두 사용할 수 있습니다 shift라는 효율적인 지연 기능을 가지고 : 여기에 코드의 버전을 노력하고 있습니다. 지금 V에 존재하는 다른 새로운 기능의 무리가로

도 살펴 here를 타고> = 1.9.5

그래서 V에서> = 1.9.5 우리는 간단하게 할 수있는

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

v 이하에도 불구하고 < 1.9.5 당신은 내가 지정한 여러 가지 이유로 모두 함께 ifelse을 피하는 것이 좋습니다 대신 다음과 같은 방법으로 두 번째 질문에 대해서는

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

에서이 기능을 만드는 .N의 사용을 만들 수 here

한 가지 대안이 될 것이다 단지

foo[, quality_1 := quality][quality == 'low' & quality_lag == 'high', quality_1 := "high"] 

이 솔루션은 두 번 [.data.table를 호출하는 약간의 오버 헤드가 같이 간단한 색인을 사용하지만 여전히 훨씬 더 효율적입니다/ifelse 솔루션보다 안전합니다.

-3

문제는 ifelse(NA, 1, 2) == NA이고, NA == 'low' 일 때 결과는 NA입니다. 쉬운 해결 방법은 지연 기능에서 문자열로 NA을 나타내는 것입니다. (?shift를보고, 너무 몇 가지 추가 기능이 있습니다) 선발 투수를 들어

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

'is.na ("NA") # [1] FALSE'이 아니기 때문에 ** 반드시 NA를 문자로 표현해서는 안됩니다. –