我正在读一本名为“R简介”的教科书,它给了我一个我完全无法理解的例子。
示例说明了
作为一个人为但可爱的例子,考虑2乘2矩阵的决定因素[a,b; c,d] 其中每个条目都是0,1,...范围内的非负整数。 。 。 ,9,这是一个数字。 问题是要找到这种形式的所有可能矩阵的决定因素ad-bc 并表示每个值作为高密度图出现的频率。这个 如果选择每个数字,则相当于找到行列式的概率分布 独立且统一随意。
它提供代码:
d <- outer(0:9, 0:9)
fr <- table(outer(d, d, "-"))
plot(as.numeric(names(fr)), fr, type="h",
xlab="Determinant", ylab="Frequency")
我只知道第一行是做什么的,但不知道outer()函数中的“ - ”符号以及table()在这种情况下做了什么。另外,为什么在最后一个plot()函数中使用name()函数
答案 0 :(得分:3)
也许我应该首先用一个非常小的例子来解释这个。我们假设我们只想查找行列式ad - bc
的分布,其中a, b, c, d
为0或1。
第一行
product <- outer(0:1, 0:1, "*")
# [,1] [,2]
#[1,] 0 0
#[2,] 0 1
计算配对产品的所有可能结果,即
0 * 0 = 0
0 * 1 = 0
1 * 0 = 0
1 * 1 = 1
这会映射到ad
中bc
和ad - bc
的可能结果。
第二行:
minus <- outer(product, product, "-")
, , 1, 1
[,1] [,2]
[1,] 0 0
[2,] 0 1
, , 2, 1
[,1] [,2]
[1,] 0 0
[2,] 0 1
, , 1, 2
[,1] [,2]
[1,] 0 0
[2,] 0 1
, , 2, 2
[,1] [,2]
[1,] -1 -1
[2,] -1 0
计算ad - bc
的所有可能结果。也许它不容易阅读,因为它们是4D阵列。那怎么样:
minus <- as.numeric(minus)
#[1] 0 0 0 1 0 0 0 1 0 0 0 1 -1 -1 -1 0
然后是时候制作一份可能结果的列联表:
fr <- table(minus)
#-1 0 1
# 3 10 3
最后,示例代码绘制了此表。
您觉得很难阅读outer
的结果,每次申请outer
时,维度都会增长。例如,将outer
应用于两个1D向量会产生2D矩阵,而进一步将outer
应用于两个2D矩阵会产生4D数组。
为了便于理解,我会每次使用as.numeric()
来平展outer
的结果。我会用这个:
product <- as.numeric(outer(0:1,0:1,"*"))
#[1] 0 0 0 1
minus <- as.numeric(outer(product, product, "-"))
#[1] 0 0 0 1 0 0 0 1 0 0 0 1 -1 -1 -1 0
plot(table(minus))
原来我的问题是:
product <- as.numeric(outer(0:9,0:9,"*"))
minus <- as.numeric(outer(product, product, "-"))
plot(table(minus))
答案 1 :(得分:2)
功能帮助页面可以轻松回答您的所有问题。
outer(0:9,0:9)
创建一个10x10矩阵测试用例。
"-"
是在outer()
默认值为*
,因此outer()
的第一个实例将0:9
的两个向量相乘,而第二个实例则要求减法-
。
table()
来自帮助:
表使用交叉分类因子来构建每个因子水平组合的计数的列联表。
names()
给出fr
输出 fr
是一个命名向量。要根据名称绘制值(在本例中为行列式),必须从fr
表中提取名称并强制转换为数字类型。
答案 2 :(得分:1)
第一行是对序列0:9
进行所有可能的产品组合(请参阅帮助FUN="*"
)。所以这是一个矩阵:
d <- outer(0:9, 0:9)
str(d)
num [1:10, 1:10] 0 0 0 0 0 0 0 0 0 0 ...
> tail(d)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[5,] 0 4 8 12 16 20 24 28 32 36
[6,] 0 5 10 15 20 25 30 35 40 45
[7,] 0 6 12 18 24 30 36 42 48 54
[8,] 0 7 14 21 28 35 42 49 56 63
[9,] 0 8 16 24 32 40 48 56 64 72
[10,] 0 9 18 27 36 45 54 63 72 81
第二行正在完成前一个矩阵的所有可能组合的差异。结果就像计算ab - bc
一样。这是一个四维数组
dd<- outer(d, d, "-")
str(dd)
num [1:10, 1:10, 1:10, 1:10] 0 0 0 0 0 0 0 0 0 0 ...
第三行计算所有可能结果的频率。名称是字符串(文本)格式的数字。
fr <- table(outer(d, d, "-"))
str(fr)
'table' int [1:163(1d)] 19 1 2 2 3 2 4 2 4 41 ...
- attr(*, "dimnames")=List of 1
..$ : chr [1:163] "-81" "-80" "-79" "-78" ...
要绘制结果,您需要x轴上的数字和y轴上的频率。
plot(as.numeric(names(fr)), fr, type="h",
xlab="Determinant", ylab="Frequency")
答案 3 :(得分:1)
在第一行中,outer()
与默认设置一起使用,默认设置是两个矩阵的外积。这就是为什么它是10x10矩阵。例如,对于第一列,它使用Y的第一个元素生成X的所有值。然后对于第二列,使用Y的第二个元素生成X的所有元素。
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 0 0 0 0 0 0 0 0 0
[2,] 0 1 2 3 4 5 6 7 8 9
[3,] 0 2 4 6 8 10 12 14 16 18
[4,] 0 3 6 9 12 15 18 21 24 27
[5,] 0 4 8 12 16 20 24 28 32 36
[6,] 0 5 10 15 20 25 30 35 40 45
[7,] 0 6 12 18 24 30 36 42 48 54
[8,] 0 7 14 21 28 35 42 49 56 63
[9,] 0 8 16 24 32 40 48 56 64 72
[10,] 0 9 18 27 36 45 54 63 72 81
然后outer(x,y,"-")
将为您提供以下结果。它将从x元素中删除y个元素。
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 -1 -2 -3 -4 -5 -6 -7 -8 -9
[2,] 1 0 -1 -2 -3 -4 -5 -6 -7 -8
[3,] 2 1 0 -1 -2 -3 -4 -5 -6 -7
[4,] 3 2 1 0 -1 -2 -3 -4 -5 -6
[5,] 4 3 2 1 0 -1 -2 -3 -4 -5
[6,] 5 4 3 2 1 0 -1 -2 -3 -4
[7,] 6 5 4 3 2 1 0 -1 -2 -3
[8,] 7 6 5 4 3 2 1 0 -1 -2
[9,] 8 7 6 5 4 3 2 1 0 -1
[10,] 9 8 7 6 5 4 3 2 1 0
但请记住,我们在向量中做了这个外部减函数。在您的示例中,它们也是10x10矩阵。因此,他们将生成多个矩阵。表就是为了这个。
names(fr)
使所有表元素成为字符串向量(!)(区别),as.numeric()
用于强制它们为数字。