2012-08-02 65 views
13

Có phải một cách thanh lịch để làm điều này nhưng tôi không thể hình dung ra như vậy:tạo ra một ma trận tam giác

Cột là xác suất 1-0 đi đúng

Hàng được xác suất 0-1 đi xuống

đang kludgy này tạo ra xem kết quả mong muốn (nhưng tôi muốn làm điều đó với một ma trận lớn hơn nhiều so này):

# Vector entries are rowname - colname, if >= 0 
# 
rb0 <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA, 0) 
rb1 <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA, 0,.1) 
rb2 <- c(NA,NA,NA,NA,NA,NA,NA,NA, 0,.1,.2) 
rb3 <- c(NA,NA,NA,NA,NA,NA,NA, 0,.1,.2,.3) 
rb4 <- c(NA,NA,NA,NA,NA,NA, 0,.1,.2,.3,.4) 
rb5 <- c(NA,NA,NA,NA,NA, 0,.1,.2,.3,.4,.5) 
rb6 <- c(NA,NA,NA,NA, 0,.1,.2,.3,.4,.5,.6) 
rb7 <- c(NA,NA,NA, 0,.1,.2,.3,.4,.5,.6,.7) 
rb8 <- c(NA,NA, 0,.1,.2,.3,.4,.5,.6,.7,.8) 
rb9 <- c(NA, 0,.1,.2,.3,.4,.5,.6,.7,.8,.9) 
rb10 <- c(0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1) 
indbias <- rbind(rb0,rb1,rb2,rb3,rb4,rb5,rb6,rb7,rb8,rb9,rb10) 
colnames(indbias) <- seq(1,0,by=-.1) 
rownames(indbias) <- seq(0,1,by=.1) 
indbias 

Cảm ơn!

Trả lời

3
require(matlab) 
x=matrix(seq(0,1,.1),1) 
X=x[rep(1,c(11)),] 
X[upper.tri(X)]=NA 
X=t(X) 
for(a in 1:11){ 
    X[1:a,a]=rev(X[1:a,a]) 
} 
X=flipud(X) 
colnames(X) <- seq(1,0,by=-.1) 
rownames(X) <- seq(0,1,by=.1) 
+0

Tôi đã sửa định dạng mã của bạn, nhưng tôi cũng đã bỏ phiếu cho bạn vì kết quả không giống bất cứ thứ gì mà OP yêu cầu. :-( – GSee

+0

Xin cảm ơn, GSee Tôi đã chỉnh sửa mã của mình để sửa chữa nó – AGS

+0

cảm ơn bạn đã rút gọn.Chuyển sang số – GSee

5

Một cách có thể, sử dụng thư viện yêu thích hiện tại của tôi:

library(plyr) 
daply(expand.grid(x=seq(1,0,-.1), y=seq(0,1,.1)), 
     .(y, x), with, 
     if (x+y >= 1) x+y-1 else NA) 

này cho kết quả sau:

 x 
y  0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 
    0 NA NA NA NA NA NA NA NA NA NA 0.0 
    0.1 NA NA NA NA NA NA NA NA NA 0.0 0.1 
    0.2 NA NA NA NA NA NA NA NA 0.0 0.1 0.2 
    0.3 NA NA NA NA NA NA NA 0.0 0.1 0.2 0.3 
    0.4 NA NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4 
    0.5 NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 
    0.6 NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 
    0.7 NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 
    0.8 NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 
    0.9 NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 
    1 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 

Ý tưởng là các expand.grid tạo ra một khung dữ liệu của tất cả các thể giá trị ô. Bạn cũng có thể sử dụng merge cho việc này. Sau đó, bạn áp dụng một hàm cho mỗi giá trị này để tính toán nội dung ô. Và có daply biến điều này thành một ma trận tốt đẹp cho bạn, bao gồm cả tên.

EDIT:
OK, bạn muốn các cột được gắn nhãn theo thứ tự ngược lại. ddply sẽ sắp xếp chúng tăng dần. Vì vậy hãy thử này:

daply(expand.grid(x=seq(0,1,.1), y=seq(0,1,.1)), 
     .(y, x), with, 
     if (y-x >= 0) y-x else NA)[,11:1] 
 x 
y  1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0 
    0 NA NA NA NA NA NA NA NA NA NA 0.0 
    0.1 NA NA NA NA NA NA NA NA NA 0.0 0.1 
    0.2 NA NA NA NA NA NA NA NA 0.0 0.1 0.2 
    0.3 NA NA NA NA NA NA NA 0.0 0.1 0.2 0.3 
    0.4 NA NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4 
    0.5 NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 
    0.6 NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 
    0.7 NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 
    0.8 NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 
    0.9 NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 
    1 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 
18
mat <- matrix(NA, 10,10) 
mat[row(mat)+col(mat) >=11] <- (row(mat)+col(mat) -11)[row(mat)+col(mat)>=11]/10 
mat 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
[1,] NA NA NA NA NA NA NA NA NA 0.0 
[2,] NA NA NA NA NA NA NA NA 0.0 0.1 
[3,] NA NA NA NA NA NA NA 0.0 0.1 0.2 
[4,] NA NA NA NA NA NA 0.0 0.1 0.2 0.3 
[5,] NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4 
[6,] NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 
[7,] NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 
[8,] NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 
[9,] NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 
[10,] 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 

Tôi nghĩ rằng đây sẽ nhanh hơn nhiều so với một giải pháp plyr và tôi tình cờ nghĩ rằng đó là dễ dàng hơn để hiểu. Về cơ bản, nó thiết lập một thử nghiệm cho các mục nằm trong "tam giác" dưới bên phải và sau đó chia kết quả của ma trận "thử nghiệm" đó 10. Bạn có thể xem ma trận thử nghiệm với mã này:

row(mat)+col(mat) -11 

Chỉnh sửa: Tôi nghĩ rằng có thể làm cho ma trận một lần như sebastian-c minh họa và sau đó thực hiện một thử nghiệm đơn để thực hiện cài đặt NA có thể nhanh hơn (với 1/3 số cuộc gọi đến rowcol) một phần ba nhanh. Dường như hai cuộc gọi seq mất nhiều thời gian hơn so với phụ:

mat <- round(outer(seq(-0.5, 0.5, 0.1), seq(-0.5, 0.5, 0.1), `+`), 1) 
is.na(mat) <- row(mat)+col(mat) <= 11 
mat 

Tôi đã tìm thấy một giải pháp dựa trên ít được biết đến embed chức năng:

mat <- embed(seq(-1,1, by=0.1), 11)[,11:1] 
is.na(mat) <- row(mat)+col(mat) <= 11 

Mặc dù nó là nhanh hơn so với mới 50% giải pháp, nó vẫn còn chậm hơn so với bản gốc.

+0

(+1) Giải pháp thanh lịch và nhanh chóng – chl

9

Một giải pháp hơi khác nhau, gần gũi trong phong cách để @ DWin của:

Tạo một ma trận với tam giác thấp thích hợp (Tôi không nghĩ rằng làm tròn là thực sự cần thiết, nhưng nếu không thì lỗi dấu chấm động làm cho nó trông khủng khiếp):

mat <- round(outer(seq(-0.5, 0.5, 0.1), seq(-0.5, 0.5, 0.1), `+`), 1) 
mat 

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] 
[1,] -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 
[2,] -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 
[3,] -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 
[4,] -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 
[5,] -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 
[6,] -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 
[7,] -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 
[8,] -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 
[9,] -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 
[10,] -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 
[11,] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 

Đảo ngược cột

mat <- mat[,rev(seq.int(ncol(mat)))] 

Tháo tam giác trên:

mat[upper.tri(mat)] <- NA 

lại đảo ngược các cột:

mat <- mat[,rev(seq_len(ncol(mat)))] 
mat 

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] 
[1,] NA NA NA NA NA NA NA NA NA NA 0.0 
[2,] NA NA NA NA NA NA NA NA NA 0.0 0.1 
[3,] NA NA NA NA NA NA NA NA 0.0 0.1 0.2 
[4,] NA NA NA NA NA NA NA 0.0 0.1 0.2 0.3 
[5,] NA NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4 
[6,] NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 
[7,] NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 
[8,] NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 
[9,] NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 
[10,] NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 
[11,] 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 

Bạn có thể thay đổi rownames từ đó.

CHỈNH SỬA: Do có rất nhiều giải pháp, bạn có thể quan tâm để xem cách chúng điểm chuẩn. Sử dụng microbenchmark:

Unit: microseconds 
    expr  min   lq  median   uq  max 
1 AGS() 682.491 738.9370 838.0955 892.8815 4518.740 
2 DW() 23.244 27.1680 31.3930 34.8650 70.937 
3 MvG() 15469.664 15920.4820 17352.3215 17827.4380 18989.270 
4 SC() 118.629 131.4575 144.1360 157.7190 631.779 

@ Giải pháp của DWIN dường như là nhanh nhất theo tỷ lệ hoàn toàn.

+0

Làm điểm chuẩn đó là một ý tưởng hay! – MvG

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