R 函数中的矩阵计算
Posted
技术标签:
【中文标题】R 函数中的矩阵计算【英文标题】:Matrix calculations within an R function 【发布时间】:2022-01-15 08:18:13 【问题描述】:我正在尝试编写一个函数,该函数将识别 nxm 矩阵 M 的哪一行最接近长度为 m 的向量 y。
请问我在代码中做错了什么?我的目标是让函数产生一个长度为 n 的列向量,它给出矩阵的每一行坐标与向量 y 之间的距离。然后我想输出最接近向量点的矩阵的行号。
closest.point <- function(M, y)
p <- length(y)
k <- nrow(M)
T <- matrix(nrow=k)
T <- for(i in 1:n)
for(j in 1:m)
(X[i,j] - x[j])^2 + (X[i,j] - x[j])^2
W <- rowSums(T)
max(W)
df[which.max(W),]
【问题讨论】:
【参考方案1】:即使已经有更好的方法(在处理矩阵时不使用 for 循环)来解决这个问题,我还是想用 for 循环为您的方法提供一个解决方案。
您的函数中有一些错误。有一些未定义的变量,例如 n、m 或 X。
同时尽量避免将变量命名为 T,因为 R 将 T 解释为 TRUE。它可以工作,但如果在以下代码行中使用 T 作为 TRUE,可能会导致一些错误。
循环时,您需要为要更新的变量提供索引,例如 T.matrix[i, j] 而不仅仅是 T.matrix,因为这将在每次迭代时覆盖 T.matrix。
closest.point <- function(M, y)
k <- nrow(M)
m <- ncol(M)
T.matrix <- matrix(nrow = k, ncol = m)
for (i in 1:k)
for (j in 1:m)
T.matrix[i, j] <- (M[i,j] - y[j])^2 + (M[i,j] - y[j])^2
W <- rowSums(T.matrix)
return(which.min(W))
# example 1
closest.point(M = rbind(c(1, 1, 1),
c(1, 2, 5)),
y = cbind(c(1, 2, 5)))
# [1] 2
# example 2
closest.point(M = rbind(c(1, 1, 1, 1),
c(1, 2, 5, 7)),
y = cbind(c(2, 2, 6, 2)))
# [1] 2
【讨论】:
谢谢,我同意其他解决方案更简洁,但这确实有助于我理解为什么我的未定义变量等不起作用。【参考方案2】:您应该尽量避免使用for
循环对向量和矩阵进行运算。 dist
基本函数计算距离。然后which.min
会给你最小距离的索引。
set.seed(0)
M <- matrix(rnorm(100), ncol = 5)
y <- rnorm(5)
closest_point <- function(M, y)
dist_mat <- as.matrix(dist(rbind(M, y)))
all_distances <- dist_mat[1:nrow(M),ncol(dist_mat)]
which.min(all_distances)
closest_point(M, y)
#>
#> 14
由reprex package (v2.0.1) 于 2021 年 12 月 10 日创建
希望这是有道理的,如果您有任何问题,请告诉我。
【讨论】:
这更整洁 - 非常感谢。【参考方案3】:这里有很多问题
-
p 已定义但从未使用过。
虽然没有错,但 T 不一定是矩阵。让它成为一个向量就足够了。
虽然使用 T 作为变量是危险的,但没有错,因为 T 也意味着 TRUE。
代码定义了 T,然后在下一条语句中立即将其丢弃,并覆盖它。从未使用过定义 T 的先前语句。
for 的值始终为 NULL,因此将其分配给 T 毫无意义。
双 for 循环不执行任何操作。其中没有分配,因此循环无效。
循环指的是 m、n、X 和 x,但这些都没有定义。
(X[i,j] - x[j])^2 重复。只需要一次。
在一行上单独写入 max(W) 无效。如果直接在控制台中完成,它只会导致打印完成。如果在函数中完成,则没有效果。如果您打算打印它,请编写 print(max(W))。
我们想要最近的点,而不是最远的点,所以 max 应该是 min。
df 用在最后一行,但没有在任何地方定义。
没有测试运行,问题是不完整的。
我已尝试进行最少的更改以使其正常工作:
closest.point <- function(M, y)
nr <- nrow(M)
nc <- ncol(M)
W <- numeric(nr) # vector having nr zeros
for(i in 1:nr)
for(j in 1:nc)
W[i] <- W[i] + (M[i,j] - y[j])^2
print(W)
print(min(W))
M[which.min(W),]
set.seed(123)
M <- matrix(rnorm(12), 4); M
## [,1] [,2] [,3]
## [1,] -0.56047565 0.1292877 -0.6868529
## [2,] -0.23017749 1.7150650 -0.4456620
## [3,] 1.55870831 0.4609162 1.2240818
## [4,] 0.07050839 -1.2650612 0.3598138
y <- rnorm(3); y
## [1] 0.4007715 0.1106827 -0.5558411
closest.point(M, y)
## [1] 0.9415062 2.9842785 4.6316069 2.8401691 <--- W
## [1] 0.9415062 <--- min(W)
## [1] -0.5604756 0.1292877 -0.6868529 <-- closest row
也就是说,最近行的计算可以在这个函数中用一行来完成。我们转置 M,然后从中减去 y,这将从每列中减去 y,但转置的列是 M 的行,因此从每一行中减去 y。然后取平方差的列总和,找出哪个最小。使用那个下标M。
closest.point2 <- function(M, y)
M[which.min(colSums((t(M) - y)^2)), ]
closest.point2(M, y)
## [1] -0.5604756 0.1292877 -0.6868529 <-- closest row
【讨论】:
谢谢 - 问题列表真的很有帮助。以上是关于R 函数中的矩阵计算的主要内容,如果未能解决你的问题,请参考以下文章
R语言使用kernlab包中的ksvm函数构建支持向量机SVM模型(Support vector machines)使用RBF核函数使用table函数计算混淆矩阵评估分类模型性能
R语言(数值列表矩阵)上应用函数(sqrtroundmeanlog)将矩阵所有数据求对数就矩阵整体的均值使用apply函数计算矩阵matrix的行均值列均值trim设置返回结果精度
R语言(数值列表矩阵)上应用函数(sqrtroundmeanlog)将矩阵所有数据求对数就矩阵整体的均值使用apply函数计算矩阵matrix的行均值列均值trim设置返回结果精度
R语言使用party包中的cforest函数基于条件推理决策树(Conditional inference trees)构建随机森林使用varimp函数查看特征重要度使用table函数计算混淆矩阵
R语言使用e1071包中的svm函数构建支持向量机SVM模型(Support vector machines)默认使用RBF核函数使用table函数计算混淆矩阵评估分类模型性能
R语言使用caret包的confusionMatrix函数计算混淆矩阵使用编写的自定义函数可视化混淆矩阵(confusion matrix)