2013-04-08 33 views
5

Chỉ để xóa một số nội dung cho bản thân, tôi muốn hiểu rõ hơn khi nào các bản sao được tạo và khi chúng không ở trong data.table. Như câu hỏi này chỉ ra Understanding exactly when a data.table is a reference to (vs a copy of) another data.table, nếu một người chỉ đơn giản là chạy dữ liệu sau rồi bạn kết thúc sửa đổi bản gốc:tìm hiểu các thuộc tính tham chiếu của dữ liệu. Có thể trong R

library(data.table) 

DT <- data.table(a=c(1,2), b=c(11,12)) 
print(DT) 
#  a b 
# [1,] 1 11 
# [2,] 2 12 

newDT <- DT  # reference, not copy 
newDT[1, a := 100] # modify new DT 

print(DT)   # DT is modified too. 
#  a b 
# [1,] 100 11 
# [2,] 2 12 

Tuy nhiên, nếu một thực hiện điều này (ví dụ), sau đó bạn kết thúc sửa đổi phiên bản mới:

DT = data.table(a=1:10) 
DT 
    a 
1: 1 
2: 2 
3: 3 
4: 4 
5: 5 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

newDT = DT[a<11] 
newDT 
    a 
1: 1 
2: 2 
3: 3 
4: 4 
5: 5 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

newDT[1:5,a:=0L] 

newDT 
    a 
1: 0 
2: 0 
3: 0 
4: 0 
5: 0 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

DT 
    a 
1: 1 
2: 2 
3: 3 
4: 4 
5: 5 
6: 6 
7: 7 
8: 8 
9: 9 
10: 10 

theo tôi được biết, lý do điều này xảy ra là bởi vì khi bạn thực hiện một tuyên bố i, data.table trả về một bảng hoàn toàn mới như trái ngược với một tham chiếu đến bộ nhớ bị chiếm đóng bởi các yếu tố lựa chọn của người già data.table. Điều này có đúng không?

EDIT: xin lỗi tôi có nghĩa là i không j (thay đổi này ở trên)

+0

Ngay cả 'newDT <- DT [x <11] 'sẽ tạo một bản sao. Thực hiện, 'newDT [, b: = 5]' sau khi tạo 'newDT' bằng cách subsetting. Sử dụng 'tracemem' và' .Internal (inspect (.)) 'Là các công cụ cung cấp thông tin để hiểu điều này. – Arun

+0

@Arun: Tôi xin lỗi tôi không chắc chắn tôi hiểu điểm của bạn .. bạn có thể giải thích những gì bạn đang đề cập đến không? bạn có ý nói rằng ví dụ đầu tiên sẽ làm việc giống như ví dụ thứ hai? trong trường hợp đó có - đó là sự thật. tôi chỉ muốn một ví dụ riêng để làm rõ mọi thứ. – Alex

+0

chắc chắn, bạn có thể giải thích câu lệnh 'j' nào bạn đang đề cập đến ở đây không:' Như tôi đã hiểu, lý do điều này xảy ra là vì khi bạn thực hiện câu lệnh j, chỉ để chắc chắn. Tôi sẽ viết một câu trả lời với những gì tôi đã nói về sau đó. – Arun

Trả lời

7

Khi bạn tạo newDT trong ví dụ thứ hai, bạn đang đánh giá i (không j). := gán theo tham chiếu trong đối số j. Không có sự tương đương trong câu lệnh i, vì tham chiếu tự phân bổ các cột, chứ không phải các hàng.

A data.table là một danh sách. Nó có chiều dài == số cột, nhưng được phân bổ quá mức, do đó bạn có thể bổ sung thêm cột mà không cần sao chép toàn bộ bảng (ví dụ sử dụng := trong j)

Nếu chúng ta kiểm tra việc data.table, sau đó chúng ta có thể thấy truelength (tl = 100) - đó là numbe khe trỏ cột

.Internal(inspect(DT)) 
@1427d6c8 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=1, tl=100) 
    @b249a30 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,... 

trong mỗi phần tử data.table có chiều dài 10, và tl=0. Hiện tại không có phương pháp nào để tăng các cột truelength để cho phép thêm hàng bổ sung theo tham chiếu.

Từ ?truelength

Hiện nay, nó chỉ là vector danh sách các con trỏ cột đó là quá phân bổ (tức truelength (DT)), không phải là vectơ cột bản thân, mà sẽ trong tương lai cho phép hàng nhanh chèn()

Khi bạn đánh giá i, data.table không kiểm tra xem bạn đã chỉ đơn giản là trở lại tất cả các hàng theo thứ tự như trong bản gốc (và sau đó không chỉ sao chép trong trường hợp đó), nó chỉ đơn giản trả về bản sao .

+0

Câu trả lời xuất sắc, như thường lệ! Tôi sẽ lưu các sự xấu hổ và loại bỏ câu trả lời của tôi :). – Arun

+0

@mnel: tôi nghĩ rằng tôi không hoàn toàn rõ ràng với câu hỏi của tôi hoặc tôi không hoàn toàn hiểu câu trả lời của bạn. tôi có nghĩa là để hiểu liệu, khi bạn đánh giá 'i', một bản sao được trả lại và không phải là một tham chiếu .. đó là sự thật? – Alex

+0

@ Alex chính xác - Tôi đã viết lại tuyên bố cuối cùng của tôi (mà trên lần đọc thứ hai không rõ ràng) – mnel

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