【问题标题】:Identify all cells above or below a diagonal in an asymmetric matrix in R识别R中不对称矩阵中对角线上方或下方的所有单元格
【发布时间】:2021-06-17 03:26:01
【问题描述】:

我四处寻找解决这个问题的方法,我发现最接近的是:Get upper triangular matrix from nonsymmetric matrix,但这对我不起作用。

我在 R 中有一个 2 列和 3000 多行的矩阵。

head(diag_calc)
        X            Y
[1,] 0.4991733   0.05358506
[2,] 1.1758962   0.70707194
[3,] 0.2197383  -0.00148791
[4,] 0.6389240   0.24411083
[5,] 0.8708275   0.16959840
[6,] 0.9784328   0.10341456

当我将它们相互绘制时,它们看起来像这样:

我想识别所有包含对角线两端点的行。我尝试通过位于 X 的第三个四分位数和 Y 的第一个四分位数来标记点,并将它们着色为橙色。我做了相反的事情并将它们涂成紫色。然而,这个指标并没有捕捉到我系统中真正的生物变异性,而且似乎识别对角线(从我标记的四分位数的拐点开始)处于极端位置的细胞会提供更好的结果。

我曾尝试使用基础 R 中的 diag、upper.tri 和 lower.tri,但这些不起作用,我认为是由于我的矩阵的不对称性质。 Diag 确实可以计算每条对角线穿过的拐点。因此:

diag_calc <- Ad_SF7_fc_scored_NK %>%
      select(one_of("X", "Y")) %>%
      as.matrix(.) 

diag(diag_calc) -> diag_test

diag_test
[1] 0.4991733 0.7070719

我可以通过在生成矩阵时交换 X 和 Y 变量来获得另一个拐点。

有人对潜在的使用方法有解决方案或建议吗?

谢谢!

【问题讨论】:

  • 在 3000x2 数据矩阵上使用 diagupper.trilower.tri 没有意义。例如diag 只返回 row1/col1 和 row2/col2。尝试绘制您的数据,然后添加abline(v=quantile(diag_calc$Y)[2:4], lty=3)abline(h=quantile(diag_calc$X)[2:4], lty=3)。这会将您的数据分成 4x4 块。
  • 我还需要量化每个对角线的每个极端点的数量,因此我需要在实际数据矩阵中识别这些单元格。
  • 你是如何定义绘图上的对角线的?

标签: r matrix diagonal


【解决方案1】:

这是一种假设您如何定义对角线的方法。首先创建可重现的数据并获取分位数:

set.seed(42)
X <- rnorm(500, 1.5, .5)
Y <- rnorm(500)
Xq <- quantile(X)
Yq <- quantile(Y)
df <- data.frame(X, Y)

现在绘制数据并确定一条穿过左下分位数交点和右上分位数交点的线。然后用斜率识别通过左上角和右下角交叉点的平行线:

plot(X~Y, df, pch=20)
abline(v=Yq[2:4], lty=3)
abline(h=Xq[2:4], lty=3)
diag <- lm(Xq[c(2, 4)]~Yq[c(2, 4)])
points(Yq[c(2, 4)], Xq[c(2, 4)], cex=2, col="red", lwd=2)
abline(diag)
b <- coef(diag)[2]
a1 <- Xq[4] - b * Yq[2]
a2 <- Xq[2] - b * Yq[4]
abline(a1, b)
abline(a2, b)

现在确定这两条线上方和下方的点:

res1 <- X - (a1 + b * Y)
res2 <- (a2 + b * Y) - X
clr <- c("black", "purple", "darkorange")
idx <- ifelse(res1 > 0, 3, ifelse(res2 > 0, 2, 1))
plot(X~Y, pch=20, col=clr[idx])
abline(a1, b, col="red")
abline(a2, b, col="red")

最后将异常值的标识添加到数据中:

position <- c("inside", "below", "above")
df$outlier <- position[idx]
head(df)
#           X            Y outlier
# 1  2.185479  1.029140719  inside
# 2  1.217651  0.914774868   below
# 3  1.681564 -0.002456267  inside
# 4  1.816431  0.136009552  inside
# 5  1.702134 -0.720153545  inside
# 6  1.446938 -0.198124330  inside
# 7  2.255761 -1.029208806   above
# 8  1.452670 -0.966955896  inside
# 9  2.509212 -1.220813089   above
# 10 1.468643  0.836207704  inside

【讨论】:

  • 谢谢卡尔森博士!事实证明,这个问题比我预期的要困难得多。这是一个很好的解决方案!
猜你喜欢
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多