2015-01-29 23 views
5

Tôi có một data.table đầy đủ của một số sản phẩm tiêu dùng. Tôi đã tạo ra một số khác biệt cho các sản phẩm là 'low', 'high' hoặc chất lượng 'unknown'. Dữ liệu là chuỗi thời gian và tôi quan tâm đến việc làm mịn một số tính thời vụ trong dữ liệu. Nếu phân loại thô của sản phẩm (phân loại được phân loại theo thuật toán tôi đã sử dụng để xác định chất lượng) là 'low' chất lượng trong khoảng thời gian X, nhưng phân loại thô của nó là 'high' chất lượng trong khoảng thời gian X-1, tôi phân loại lại sản phẩm đó là 'high' chất lượng trong khoảng thời gian X. Quá trình này được thực hiện trong một số loại phân biệt nhóm sản phẩm.Hành vi ifelse trong data.table (R)

Để thực hiện điều này, tôi đã có một cái gì đó như sau:

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

Lấy một cái nhìn tại 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 

Vì vậy, quality_1 chủ yếu là những gì tôi muốn. Nếu khoảng thời gian X là 'low' và khoảng thời gian X-1 là 'high', chúng tôi thấy việc phân loại lại thành 'high' xảy ra và mọi thứ còn lại chủ yếu còn nguyên vẹn từ quality. Tuy nhiên, khi quality_lag là NA, 'low' được phân loại lại thành NA trong quality_1. Đây không phải là vấn đề với 'high' hoặc 'unknown'.

Đó là, bốn hàng đầu tiên của foonên trông như thế này:

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 

Bất kỳ suy nghĩ về những gì đang gây ra điều này?

+7

Để bắt đầu, bạn không cần phải tái tạo lại bánh xe. 'data.table' v> = 1.9.5 đã có hàm' lag' được gọi là 'shift', vì vậy bạn chỉ có thể thực hiện' foo [, quality_lag: = shift (chất lượng), bởi = group] ' –

+6

Thứ hai,' ifelse' thực sự là một chức năng bất chính và tôi luôn cố gắng tránh nó. Lời khuyên của tôi sẽ chỉ làm một cái gì đó như 'foo [, quality_1: = quality] [chất lượng == 'thấp' & quality_lag == 'cao', chất lượng_1: =" cao "]' –

+1

@DavidArenburg 's điểm là chết trên. Ngoài ra, hãy xem http://stackoverflow.com/q/16275149/1492421 để biết thêm thông tin về ifelse –

Trả lời

6

Đối với người mới bắt đầu, các Development version on GitHub đã có một chức năng lag hiệu quả gọi là shift mà có thể được sử dụng cả hai như là lag hoặc chì (và có một số chức năng bổ sung quá, xem ?shift).

cũng Hãy xem here là có một loạt các chức năng mới khác mà bây giờ có mặt trong v> = 1.9.5

Vì vậy, dưới v> = 1.9.5, chúng tôi chỉ có thể làm

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

Mặc dù ngay cả dưới v < 1.9.5 bạn có thể làm cho việc sử dụng của .N thay vì tạo chức năng này theo cách sau

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

Về câu hỏi thứ hai của bạn, tôi sẽ khuyên bạn nên tránh ifelse tất cả cùng nhau vì nhiều lý do quy định here

Một có thể thay thế sẽ được , chỉ cần sử dụng một chỉ mục đơn giản như trong

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

giải pháp này có một overhead chút, gọi [.data.table hai lần nhưng nó vẫn sẽ hiệu quả hơn/an toàn hơn giải pháp ifelse.

-3

Vấn đề của bạn là ifelse(NA, 1, 2) == NA và khi bạn thực hiện NA == 'low' kết quả là NA. Sửa lỗi dễ dàng là đại diện cho NA làm các chuỗi trong hàm trễ của bạn. Dưới đây là phiên bản của mã của bạn làm việc:

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

Bạn nên ** không bao giờ ** đại diện cho NA là một nhân vật chủ yếu vì 'is.na (" NA ") # [1] FALSE' –

Các vấn đề liên quan