2011-06-28 32 views
6

Xác định:Tạo một biến chụp sự xuất hiện thường xuyên nhất bởi nhóm

df1 <-data.frame(
id=c(rep(1,3),rep(2,3)), 
v1=as.character(c("a","b","b",rep("c",3))) 
) 

s.t.

> df1 
    id v1 
1 1 a 
2 1 b 
3 1 b 
4 2 c 
5 2 c 
6 2 c 

Tôi muốn tạo ra một phần ba biến freq có chứa các quan sát thường xuyên nhất trong v1 bởi id s.t.

> df2 
    id v1 freq 
1 1 a b 
2 1 b b 
3 1 b b 
4 2 c c 
5 2 c c 
6 2 c c 
+1

các mối quan hệ phải được xử lý như thế nào trong nhóm id? – Chase

+0

@Chase Trong trường hợp của tôi, tôi chắc chắn không có mối quan hệ nào. – Fred

+0

Câu hỏi hay về quan hệ, tôi sẽ ghi chú về cách giải pháp xử lý ... – joran

Trả lời

3

Bạn có thể làm điều này bằng ddply và một chức năng tùy chỉnh để chọn ra giá trị thường gặp nhất:

myFun <- function(x){ 
    tbl <- table(x$v1) 
    x$freq <- rep(names(tbl)[which.max(tbl)],nrow(x)) 
    x 
} 

ddply(df1,.(id),.fun=myFun) 

Lưu ý rằng which.max sẽ trở lại sự xuất hiện đầu tiên của giá trị lớn nhất, trong trường hợp của các mối quan hệ . Xem ?? which.is.max trong gói nnet để có tùy chọn ngắt kết nối ngẫu nhiên.

+0

+1 Nice ........ – Andrie

1
mode <- function(x) names(table(x))[ which.max(table(x)) ] 
df1$freq <- ave(df1$v1, df1$id, FUN=mode) 
> df1 
    id v1 freq 
1 1 a b 
2 1 b b 
3 1 b b 
4 2 c c 
5 2 c c 
6 2 c c 
+0

Tôi nghĩ 'df2' là lỗi đánh máy, và khi tôi chạy cái này tôi nhận được 'NA' cho 'id' = 2. – joran

+0

Cảm ơn Joran. sửa lỗi –

+0

Lỗi đánh máy đã biến mất, nhưng tôi vẫn không nghĩ mã này hoạt động. Khi id = 2, max (table (x)) trả về 3, nhưng table (x) chỉ có 1 tên, do đó chế độ chức năng của bạn trả về NA. – joran

1

Một cách khác gồm sử dụng tidyverse chức năng:

  • nhóm đầu tiên, sử dụng group_by(), và đếm sự xuất hiện của biến thứ hai sử dụng tally()
  • sắp xếp bởi số lần xuất hiện với arrange()
  • tóm tắt và chọn hàng đầu tiên với summarize()first()

Do đó:

df1 %>% 
group_by(id, v1) %>% 
tally() %>% 
arrange(id, desc(n)) %>% 
summarize(freq = first(v1)) 

này sẽ cung cấp cho bạn chỉ là lập bản đồ (mà tôi tìm thấy sạch hơn):

# A tibble: 2 x 2 
    id freq 
    <dbl> <fctr> 
1  1  b 
2  2  c 

Bạn có thể sau đó left_join khung dữ liệu ban đầu của bạn với bảng đó.

+0

Tôi thích cách tiếp cận đó vì người ta có thể kiểm tra và xác định các mối quan hệ sau 'tally()'. Điều đó có thể là có thể với chức năng tuyệt vời của @ joran quá nhưng không quá thẳng về phía trước như ở đây, ít nhất là đối với tôi – Tjebo

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