2012-03-26 42 views
5

Mục tiêu là tạo các chỉ báo cho biến số/chuỗi trong một khung dữ liệu. Đó là dataframe có> 2mm hàng, và chạy R trên windows, tôi không có tùy chọn sử dụng plyr với. Equivalent = T. Vì vậy, tôi đang dùng con đường "chia và chinh phục" với plyr và reshape2.Tạo chỉ số trong các khung dữ liệu lớn

Chạy tan chảy và dàn diễn viên chạy ra khỏi bộ nhớ, và sử dụng

ddply(idata.frame(items) , c("ID") , function(x){ 
     ( colSums(model.matrix(~ x$element - 1)) > 0 ) 
} , .progress="text")  

hoặc

ddply(idata.frame(items) , c("ID") , function(x){ 
      ( elements %in% x$element ) 
    } , .progress="text") 

không mất một lúc. Cách tiếp cận nhanh nhất là lời gọi để nhấn mạnh bên dưới. Bạn có thấy một cách để tăng tốc độ này? Câu lệnh% in% chạy nhanh hơn lệnh gọi model.matrix. Cảm ơn.

set.seed(123) 

dd <- data.frame(
    id = sample(1:5, size=10 , replace=T) , 
    prd = letters[sample(1:5, size=10 , replace=T)] 
) 

prds <- unique(dd$prd) 

tapply(dd$prd , dd$id , function(x) prds %in% x) 
+0

Tôi bị nhầm lẫn với ví dụ của bạn. Bạn đang tách 'dd $ prd' bằng' dd $ id', sau đó hỏi giá trị của 'prds' được biểu diễn trong mỗi id - nhưng' prds' không được sắp xếp (!) Bạn có muốn 'prds <- sort (duy nhất (dd $ prd)) '(điều đó có ý nghĩa hơn với tôi ...)? –

+0

Miễn là các chỉ báo (lôgíc) tương ứng với các phần tử có sẵn trong prds có cùng thứ tự trên các ID, không quan trọng cách chúng được sắp xếp. –

+0

OK. Xem câu hỏi khác của tôi, trong câu trả lời của tôi dưới đây ... –

Trả lời

4

Đối với vấn đề này, các gói bigmemorybigtabulate có thể làm quen với bạn. Dưới đây là một ví dụ hơi tham vọng hơn:

library(bigmemory) 
library(bigtabulate) 

set.seed(123) 

dd <- data.frame(
    id = sample(1:15, size=2e6 , replace=T), 
    prd = letters[sample(1:15, size=2e6 , replace=T)] 
) 

prds <- unique(dd$prd) 

benchmark(
bigtable(dd,c(1,2))>0, 
table(dd[,1],dd[,2])>0, 
xtabs(~id+prd,data=dd)>0, 
tapply(dd$prd , dd$id , function(x) prds %in% x) 
) 

Và kết quả điểm chuẩn (Tôi đang học hỏi những điều mới tất cả các thời gian):

          test replications elapsed relative user.self sys.self user.child sys.child 
1      bigtable(dd, c(1, 2)) > 0   100 54.401 1.000000 51.759 3.817   0   0 
2     table(dd[, 1], dd[, 2]) > 0   100 112.361 2.065422 107.526 6.614   0   0 
4 tapply(dd$prd, dd$id, function(x) prds %in% x)   100 178.308 3.277660 166.544 13.275   0   0 
3    xtabs(~id + prd, data = dd) > 0   100 229.435 4.217478 217.014 16.660   0   0 

Và đó cho thấy bigtable chiến thắng hiện bởi một số lượng đáng kể. Kết quả là khá nhiều mà tất cả các prds là trong tất cả các ID, nhưng xem ?bigtable để biết chi tiết về định dạng của các kết quả.

+0

Cảm ơn bạn rất nhiều. –

+0

Việc chạy vừa hoàn thành (sử dụng bigtable) trên tập dữ liệu thực tế (!). –

1

Việc bạn sử dụng chức năng %in% có vẻ ngược lại với tôi. Và nếu bạn muốn có kết quả đúng/sai cho mỗi hàng dữ liệu thì bạn nên sử dụng% trong% dưới dạng hoạt động vectơ hoặc ave. Mặc dù không cần thiết ở đây bạn có thể muốn sử dụng nó nếu có một hàm phức tạp hơn cần thiết để áp dụng cho mọi mục.

set.seed(123) 

dd <- data.frame(
    id = sample(1:5, size=10 , replace=T) , 
    prd = letters[sample(1:5, size=10 , replace=T)] 
) 

prds <- unique(dd$prd) 
target.prds <- prds[1:2] 
dd$prd.in.trgt <- with(dd, prd %in% target.prds) 
+0

Sẽ có nhiều chỉ báo vì có 'prds' (hoặc' target.prds'): 'c (1,2,3)% trong% c (1)' sẽ chỉ ra rằng 1 là trong bản ghi đó, nhưng không phải 2 cũng không 3. –

+0

Bạn không thể chỉ xác định lại% trong% là thứ gì đó không phải. Và một khung dữ liệu cần tất cả các phần tử để có số lượng mục nhập thường xuyên trên mỗi hàng. Bạn cần sử dụng cấu trúc dữ liệu chứa một số biến nếu "lần truy cập", ... hoặc ma trận lôgic của TRUE và FALSE hoặc danh sách. –

+0

Không chắc tôi hiểu những gì bạn đang nói. Cuộc gọi đến '% in%' sẽ luôn trả về cùng một số lôgic. Tôi bắt đầu với 'hàm (x) duy nhất (x $ prd)' trong lời gọi 'tapply', và điều đó sẽ tạo ra một mảng rách rưới. –

2

Bạn có thể nói thêm một chút về cách giải quyết vấn đề về số lượng, số ID, v.v. tính toán lại sẽ tiếp cận tất cả TRUE/all 1 ...)? Tôi mong rằng xtabs sẽ nhanh hơn, nhưng nó không phải cho một ví dụ về kích thước này ...

library(rbenchmark) 
benchmark(
      tapply(dd$prd , dd$id , function(x) prds %in% x), 
      xtabs(~id+prd,data=dd)>0) 

    test  replications elapsed relative 
1 tapply(...)    100 0.053 1.000000 
2 xtabs(...) > 0   100 0.120 2.264151 
+0

Có 13,5 triệu mục (trên 780.000 ID, vì vậy nhiều mục cho mỗi ID).Có 83 yếu tố khác nhau trong prd. Cảm ơn bạn đã thu hút sự chú ý của tôi đến rbenchmark bằng cách này. –

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