识别 R 中非对称矩阵中对角线上方或下方的所有单元格

Identify all cells above or below a diagonal in an asymmetric matrix in R

我四处寻找这个问题的解决方案,我找到的最接近的是:,但这对我不起作用。

我在 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 的第一个四分位数并将它们涂成橙色来标记点。我做了相反的事情并将它们染成紫色。然而,这个指标并没有捕捉到我系统中真正的生物变异性,而且似乎识别对角线(从我标记的四分位数的拐点开始)的极端细胞会提供更好的结果。

我尝试使用 base 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 变量来获得另一个拐点。

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

谢谢!

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

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