2015-05-25 18 views
10

Tôi cố gắng để tính toán số lượng các mục phổ biến trong các yếu tố của một danh sách:Một chức năng tổng quát hơn về số lượng phù hợp với các yếu tố trong những yếu tố n của một danh sách

temp<-list(element1=c("a","b","c"), element2=c("b","c","d"), 
      element3=c("d","e","f"), element4=c("a","c","z")) 

Để có được sự chồng chéo giữa tất cả kết hợp cặp của các yếu tố, chức năng này hoạt động:

calculate.overlap.2<-function(y){ 
    pw<-combn(y,2,FUN=function(x)sum(x[[1]]%in%x[[2]])) 
    names(pw)<-combn(y,2,FUN=function(x)paste(names(x)[[1]],names(x)[[2]],sep="-")) 
    return(pw) 
} 

Để có được sự chồng chéo giữa tất cả các kết hợp ba chiều của các yếu tố, chức năng này hoạt động:

calculate.overlap.3<-function(y){ 
    pw<-combn(y,3,FUN=function(x)sum(x[[1]]%in%x[[2]]&x[[1]]%in%x[[3]])) 
    names(pw)<-combn(y,3,FUN=function(x) paste(names(x)[[1]],names(x)[[2]],names(x)[[3]],sep="-")) 
    return(pw) 
} 

nhưng như bạn có thể nói từ những con số bên trong hàm, đây không phải là một giải pháp thanh lịch.

Thật tuyệt vời khi khái quát hóa hai hàm này thành một hàm và có chức năng lấy làm đầu vào cho các phần tử trong mỗi lần kiểm tra trùng lặp. Tức là, đầu vào của number.of.elements.per.comparison=2 sẽ tương đương với calculate.overlap.2 ở trên và đầu vào cho hàm number.of.elements.per.comparison=3 sẽ giống như calculate.overlap.3.

Tôi cảm thấy như có một giải pháp rất thanh lịch cho điều này, nhưng tôi không thể nhìn thấy nó.

Trả lời

6
calculate.overlap <- function(y, i){ 
    pw <- combn(seq_along(y), i, FUN= function(x) { 
    res <- length(Reduce(intersect, y[x])) 
    names(res) <- paste(names(y[x]), collapse = "-") 
    res 
    }, simplify = FALSE) 
    do.call(c, pw) 
} 

calculate.overlap(temp, 3) 
#element1-element2-element3 element1-element2-element4 element1-element3-element4 element2-element3-element4 
#       0       1       0       0 
6

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

ix = lapply(seq_along(temp), function(u) combn(seq_along(temp), u)) 

lapply(ix, function(m){ 
    res = apply(m,2, function(v) length(Reduce(intersect, temp[v]))) 
    setNames(res, apply(m, 2, paste, collapse='-')) 
}) 

#[[1]] 
#1 2 3 4 
#3 3 3 3 

#[[2]] 
#1-2 1-3 1-4 2-3 2-4 3-4 
# 2 0 2 1 1 0 

#[[3]] 
#1-2-3 1-2-4 1-3-4 2-3-4 
# 0  1  0  0 

#[[4]] 
#1-2-3-4 
#  0 
0

Trong gói VennDiagram có một chức năng gọi là calculate.overlap mà làm chính xác điều đó. Bạn thậm chí có thể tham khảo danh sách và xem yếu tố nào nằm trong mỗi giao lộ nếu bạn cần xem chúng. Bạn có thể thực hiện chồng chéo danh sách với tối đa 5 danh sách phụ.

liên kết đến gói https://cran.r-project.org/web/packages/VennDiagram/index.html

+0

Bạn đã xem mã trong hàm đó chưa? Giải pháp của Roland tốt hơn nhiều. –

+0

Chỉ khi tất cả những gì anh ta muốn là NUMBER mục phổ biến. Nếu, bằng bất kỳ phương tiện nào, anh ta muốn biết mục nào nằm trong mỗi giao lộ, anh ta không thể. Hàm 'calculate.overlap' từ gói 'VennDiagram' cho điều đó. Vì vậy, 'venn (x) - attr (x, "intersections")' từ gói 'gplots'. – Drizzt

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