2013-09-02 49 views
5

Tôi muốn tìm sự kết hợp các giá trị thường xuyên nhất trong một data.frame.Tìm sự kết hợp giá trị thường xuyên nhất trong một data.frame

Dưới đây là một số ví dụ dữ liệu:

dat <- data.frame(age=c(50,55,60,50,55),sex=c(1,1,1,0,1),bmi=c(20,25,30,20,25)) 

Trong ví dụ này là kết quả Tôi đang tìm kiếm là sự kết hợp của tuổi = 55 tuổi, quan hệ tình dục = 1 và bmi = 25, vì đó là sự kết hợp thường gặp nhất của cột giá trị.

Dữ liệu thực của tôi có khoảng 30000 hàng và 20 cột. Điều gì sẽ là một cách hiệu quả để tìm ra sự kết hợp phổ biến nhất trong số 20 giá trị này trong số 30000 quan sát?

Rất cám ơn!

Trả lời

7

Dưới đây là một cách tiếp cận với data.table:

dt <- data.table(dat) 
setkeyv(dt, names(dt)) 
dt[, .N, by = key(dt)] 
dt[, .N, by = key(dt)][N == max(N)] 
# age sex bmi N 
# 1: 55 1 25 2 

Và một cách tiếp cận với cơ sở R:

x <- data.frame(table(dat)) 
x[x$Freq == max(x$Freq), ] 
# age sex bmi Freq 
# 11 55 1 25 2 

Tôi cũng không biết như thế nào trong số này quy mô tuy nhiên, đặc biệt là nếu số lượng kết hợp sẽ lớn. Vì vậy, kiểm tra lại và báo cáo!


Thay x$Freq == max(x$Freq) với which.max(x$Freq)N == max(N) với which.max(N) nếu bạn đang thực sự chỉ quan tâm đến một dãy kết quả.

+0

Cảm ơn bạn đã giải thích! Cách tiếp cận data.table hoạt động hoàn hảo và rất nhanh (0,31 giây trên dữ liệu của riêng tôi 30000 * 20), tuy nhiên, phương pháp R cơ sở không hoạt động trên dữ liệu của riêng tôi vì số lượng kết hợp thực sự quá lớn đối với bảng(). – Rob

+0

Chỉ cần thử 'dt [, .N, by = key (dt)] [N == mà max (N)]' bạn đề xuất chỉ nhận được một hàng, nhưng điều đó mang lại cho tôi kết quả tương tự als 'dt [,. N, by = key (dt)] [N == max (N)] '... Bất kỳ gợi ý nào về cách chỉ nhận được một hàng với sự kết hợp các giá trị phổ biến nhất? – Rob

+0

@Rob, Nó phải là 'dt [, .N, by = key (dt)] [which.max (N)]'. – A5C1D2H2I1M1N2O1R2T1

1

Một cái gì đó như thế này ??

> dat[duplicated(dat), ] 
    age sex bmi 
5 55 1 25 

sử dụng while (có thể tốn thời gian)

Đây là một data.frame với hơn 1 trường hợp nhân đôi

> dat <- data.frame(age=c(50,55,60,50,55, 55, 60), 
        sex=c(1,1,1,0,1, 1,1), 
        bmi=c(20,25,30,20,25, 25,30)) 
> dat[duplicated(dat), ] # see data.frame 
     age sex bmi 
    5 55 1 25 
    6 55 1 25 
    7 60 1 30 


# finding the most repeated item 
> while(any(duplicated(dat))){ 
    dat <- dat[duplicated(dat), ] 
    #print(dat) 
} 

> print(dat) 
    age sex bmi 
6 55 1 25 
1

Các giải pháp nhanh chóng và dơ bẩn. Tôi chắc chắn có một cách fancier để nó mặc dù, với gói plyr hoặc tương tự.

> (tab <- table(apply(dat, 1, paste, collapse=", "))) 
50, 0, 20 50, 1, 20 55, 1, 25 60, 1, 30 
     1   1   2   1 

> names(which.max(tab)) 
[1] "55, 1, 25" 
+0

'bảng (do.call (dán, dat))' cũng hoạt động. Bạn không chắc chắn về cách so sánh tốc độ với 'apply (...)' – A5C1D2H2I1M1N2O1R2T1

+0

Cảm ơn, hoạt động hoàn hảo! do.call có vẻ nhanh hơn một chút so với phương pháp áp dụng (2.00 giây so với 2.58 giây). – Rob

+0

Đó có thể là do trong giải pháp 'apply' của tôi,' paste' được gọi trên mỗi hàng, nhưng trong giải pháp 'do.call' nó chỉ được gọi một lần. Tôi rất vui vì bạn đã giải quyết câu trả lời của @ AnandaMahto, chắc chắn đó là cách để đi. – Backlin