2013-02-07 39 views
9

Tôi đã cố gắng đính kèm lớp học của riêng mình vào một numeric, để thay đổi đầu ra format. Điều này làm việc tốt, nhưng sau khi tôi làm một nhóm by lớp học trở lại số.Tại sao data.table mất định nghĩa lớp trong .SD sau khi nhóm theo?

Ví dụ: Xác định một chức năng định dạng mới cho lớp học của tôi:

format.myclass <- function(x, ...){ 
    paste("!!", x, "!!", sep = "") 
} 

Sau đó tạo một nhỏ data.table và thay đổi một trong các cột để MyClass:

> DT <- data.table(L = rep(letters[1:3],3), N = 1:9) 
> setattr(DT$N, "class", "myclass") 
> DT 
    L  N 
1: a !!1!! 
2: b !!2!! 
3: c !!3!! 
4: a !!4!! 
5: b !!5!! 
6: c !!6!! 
7: a !!7!! 
8: b !!8!! 
9: c !!9!! 

Bây giờ thực hiện một nhóm bằng và cột N chuyển thành số nguyên:

> DT[, .SD, by = L] 
    L N 
1: a 1 
2: a 4 
3: a 7 
4: b 2 
5: b 5 
6: b 8 
7: c 3 
8: c 6 
9: c 9 

> DT[, sapply(.SD, class), by = L] 
    L  V1 
1: a integer 
2: b integer 
3: c integer 

Bất kỳ ý tưởng nào tại sao?

Trả lời

8

Bởi vì bất cứ khi nào R tập hợp lại một véc tơ, nó chỉ ném đi lớp. Tại sao? Vâng, bởi vì nó là một ass, đó là lý do tại sao. Bạn cần phải viết phương thức "[" -subset.

> DT[,N] 
[1] 1 2 3 4 5 6 7 8 9 
attr(,"class") 
[1] "myclass" 
> DT[1:2,N] 
[1] 1 2 

xem cách trừ vector đã loại bỏ lớp học? Đó chính là vấn đề. data.table đang làm điều này tại một số điểm cho vector của bạn. Viết một phương pháp "[" (chỉ cần sao chép một trong những ngày sử dụng):

"[.myclass"= function (x, ..., drop = TRUE){ 
    cl <- oldClass(x) 
    class(x) <- NULL 
    val <- NextMethod("[") 
    class(val) <- cl 
    val 
} 

> DT[1:2,N] 
[1] 1 2 
attr(,"class") 
[1] "myclass" 

và bây giờ nó có một số lớp. Đây cũng sửa dòng cuối cùng của bạn với sapply:

> DT[, sapply(.SD, class), by = L] 
    L  V1 
1: a myclass 
2: b myclass 
+2

+1 cho "ass". Và một câu trả lời tuyệt vời – Corone

+3

+1 quá. Tôi đã tuyên thệ '.SD' giữ lại các thuộc tính cột nhưng rõ ràng là không. Sẽ khắc phục điều đó, trừ khi sẽ có bất kỳ nhược điểm nào? (Tôi biết sẽ không có bất kỳ nhược điểm hiệu suất nào, vì vậy tôi có ý nghĩa khác). –

+2

Tôi thực sự không biết tại sao đây không phải là hành vi mặc định. Hoặc có bao nhiêu bản sao của "[.Date" đang ngồi xung quanh trên CRAN dưới các bí danh khác nhau. Giải pháp thực sự sẽ là phân lớp từ "Ngày" và nhận hàm con đó miễn phí :) j/k – Spacedman

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