必须有一种优雅的方式来做到这一点,但我无法弄清楚:
列是从右到右的概率
行是从0到1的概率下降
这个kludgy代码产生了看到期望的结果(但我想用比这更大的矩阵来做):
# 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
谢谢!
答案 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
我认为这比plyr解决方案要快得多,我碰巧认为它更容易理解。它基本上为右下角“三角形”中的条目设置测试,然后将“测试”矩阵bu 10的结果分开。您可以使用以下代码查看测试矩阵:
row(mat)+col(mat) -11
编辑:我认为有可能将矩阵设为sebastian-c一次,然后进行单一测试来进行NA设置可能会更快(调用row
和{{的三分之一1}})但似乎只有三分之一的速度。看起来两个seq调用比额外调用需要更多时间:
col
我确实找到了另一种基于鲜为人知的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
函数的解决方案:
embed
虽然它比新解决方案快50%,但它仍然比原始解决方案慢。
答案 1 :(得分:9)
稍微不同的解决方案,与@ DWin的风格接近:
使用适当的下三角形创建一个矩阵(我不认为舍入是严格必要的,否则浮点错误会使它看起来很糟糕):
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
反转列
mat <- mat[,rev(seq.int(ncol(mat)))]
删除上三角形:
mat[upper.tri(mat)] <- NA
重新反转列:
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
您可以从那里更改rownames。
编辑:鉴于解决方案太多,您可能有兴趣了解他们的基准测试方法。使用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
@Ddin的解决方案似乎是最快的。
答案 2 :(得分:5)
一种可能的方式,使用我最喜欢的库:
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)
这给出了以下结果:
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
这个想法是expand.grid
创建了所有可能的单元格值的数据框。您也可以使用merge
。然后,将函数应用于每个值以计算单元格内容。并daply
将此变成一个很好的矩阵,包括名称。
修改强>
好的,您希望以相反的顺序标记列。 ddply
将按升序排序。所以试试这个:
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
答案 3 :(得分: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)