我想根据一个函数按行填充矩阵,该函数给出数字 seq(1) 1 seq(2) 1 2 等等的 seq()
matrixinp = matrix(data=NA, nrow=6, ncol=6)
> print(matrixinp)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA NA NA NA NA NA
[2,] NA NA NA NA NA NA
[3,] NA NA NA NA NA NA
[4,] NA NA NA NA NA NA
[5,] NA NA NA NA NA NA
[6,] NA NA NA NA NA NA
# display matrix
print(matrixinp)
# fill the elements with some
# 90 in a matrix
for (i in 1:6){
aaa<-seq(i)
print(aaa)
for(j in 1:6){
matrixinp[j,] = aaa
}
}
这给了我这个:
> print(matrixinp)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 2 3 1 2 3
[2,] 1 2 3 1 2 3
[3,] 1 2 3 1 2 3
[4,] 1 2 3 1 2 3
[5,] 1 2 3 1 2 3
[6,] 1 2 3 1 2 3
但我想要这个:
> print(matrixinp)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 NA NA NA NA NA
[2,] 1 2 NA NA NA NA
[3,] 1 2 3 NA NA NA
[4,] 1 2 3 4 NA NA
[5,] 1 2 3 4 5 NA
[6,] 1 2 3 4 5 6
我敢打赌一行代码就能解决这个问题,R 是一种矢量化语言。
创建于 2024-09-17,使用reprex v2.1.0
等一下,我打赌赢了。
诀窍是要知道 R 的矩阵是列主序的,因此使用索引矩阵,
lower.tri
值将放在正确的位置。作为函数:
你可以尝试
在哪里
diag(1:6)*NA
产生一个6-by-6
矩阵NA
lower.tri
检索下三角部分m
replace
m
根据掩码指标替换值或者,如果你想要按行进行操作
在哪里
`length<-`
将长度设置为给定的向量do.call(rbind, ...)
按行将向量堆叠在列表中1)创建一个 6x6 的对角矩阵,用列号填充它,然后 NA 出上三角。
给予
2)或者使用本机管道:
3)将 cc 定义为 6x6 矩阵,其列号如上,然后使用所示的公式。
您可以尝试以下操作,
保留初始创建的空矩阵,其中包含 NA 值。使用单个循环遍历行(1 到 6)。对于每一行 i,我们仅使用序列 seq(i) 填充前 i 列。每行中的其余元素保持初始设置的 NA。
该方法确保每行都具有直到其行号的序列,其余部分保持为 NA。
您是否特别需要使用循环来执行此操作
seq()
?你可以利用 R 的矩阵代数功能轻松地创建该矩阵:
但如果你想了解为什么你的循环不起作用:
运行时,
seq(4)
您会得到一个长度为 4 的向量c(1,2,3,4)
。然后您尝试将其分配给的每一行matrixinp
,但该矩阵中的行长度为 6 个元素。当您进行循环的第 4 次迭代时,该分配将失败并出现错误number of items to replace is not a multiple of replacement length
。在进行第 4 次迭代之前,6 是 1、2 和 3 的倍数,因此对于那些迭代,R 会用 aaa 向量的重复填充矩阵:
aaa=1
,它用填充矩阵行c(1,1,1,1,1,1)
。aaa=c(1,2)
它用 填充矩阵行c(1,2,1,2,1,2)
。aaa=c(1,2,3)
,它用填充矩阵行c(1,2,3,1,2,3)
。这就是为什么你会得到那个奇怪的矩阵,其中每一行都是 1 2 3 1 2 3 - 当 i=3 时,内部循环将 j 分配
c(1,2,3,1,2,3)
给矩阵的每一行。然后你的循环在 i=4 处遇到错误时停止,只剩下 i=3 版本的矩阵。为了帮助原始提问者理解,以下是我在给 RuiBarradas 的评论中写的一句话:
这是混乱而过于复杂的代码,因为它很愚蠢,试图在一行中完成所有事情。你通常不应该在实际代码中做这样的事情,这会让其他人难以阅读代码(或者几个月后你再次查看时难以阅读)。但它确实展示了 R 的一些有用功能,并且尝试这样的事情有时可以帮助你更多地了解 R。
最好从外向内阅读此代码,例如从最外层的函数开始:
ifelse()
是一个检查其第一个参数是否为真的函数 - 如果是,则返回其第二个参数,否则返回其第三个参数。ifelse(c(T,F,T,F),'A','B')
会回来c('A','B','A','B')
。ifelse()
是lower.tri(matrix(nrow=6,ncol=6),diag=T)
,一个 TRUE/FALSE 值矩阵,表示 6x6 矩阵中的哪些单元格位于下三角(包括对角线为“在下三角”)rep(1,6) %*% t(1:6)
,来自我对你的问题的另一个回答的矩阵代数,它创建一个列全为 1 的矩阵,列全为 2 的矩阵,等等。因此,此代码检查 6x6 矩阵的每个单元格是否位于下三角。如果是,它会从矩阵中获取该单元格的值,该单元格的列为全 1、全 2 等。但如果位于上三角,它会将该单元格设置为 NA。
我的第二句台词是:
(!upper.tri(diag(6)) | NA) * (rep(1,6) %*% t(1:6))
(!upper.tri(diag(6)) | NA)
另一个由(rep(1,6) %*% t(1:6))
diag(6)
创建一个 6x6 矩阵,对角线上为 1,其余部分为 0。其目的只是以比 更短的方式创建一个 6x6 矩阵matrix(nrow=6,ncol=6)
。!upper.tri(diag(6))
使用upper.tri()
该矩阵创建一个矩阵,其中上三角(不包括对角线)为 TRUE,下三角为 FALSE。然后它使用!
(“非”运算符)将 TRUE 转换为 false,反之亦然。lower.tri(diag(6),diag=T)
制作相同的 T/F 矩阵,但由于这要求矩阵diag=T
包含对角线,!upper.tri(diag(6))
因此写起来更短(尽管可读性较差)。(!upper.tri(diag(6)) | NA)
。我取该 T/F 矩阵,并与 NA 进行逻辑“或”。“真或 NA”计算结果为“真”,而“假或 NA”计算结果为 NA。