找到根据矩阵中特定列中的行之间的绝对差排序的子集

Posted

技术标签:

【中文标题】找到根据矩阵中特定列中的行之间的绝对差排序的子集【英文标题】:find the subset sorted according to absolute difference between rows in specific columns in a matrix 【发布时间】:2014-01-13 08:47:42 【问题描述】:

请帮助我编写以下代码。

set.seed(5)
matrix <- matrix(round(rnorm(100,100,50)), nrow = 4, ncol = 2, byrow = TRUE,
             dimnames = list(c("r1", "r2", "r3","r4"),c("c1","c2")))

我需要上面矩阵的子集/行,其中 row r1absolute differencecolumn c1 中的 rows 的其余部分。如果我可以sortdifference 的行以递增的顺序排列,那也很有用。从那里我可以找到具有minimum 差异值的行。

输入矩阵

   c1   c2
r1 10  4
r2 6   11
r3 9   17
r4 21  91

输出矩阵

   c1   c2
r1 10   4
r2 9    17
r3 6    11
r4 21   91

row r1 保留作为参考。 row r2 to r3 根据与row r1column c1 中的增加差异排序。感谢任何帮助/线索。

【问题讨论】:

你的意思是绝对差的总和吗?即j最小化sum(abs(matrix[1,3:4] - matrix[j,3:4])) @Spacedman 可能无法正确提出我的查询。我想在 column c3 first 中找到 lowest abs difference between row r1 and other rows ,然后在 sorted according to increasing abs difference in column c4 中找到。我认为min abs diff 在多列中的单行中可能并不总是可能的。我希望这次我能澄清我的疑问。 也许我刚刚发布的答案太多了。编辑您的 Q 以显示您的矩阵并显示和解释您想要的结果(在此示例中您可以手动计算) 【参考方案1】:

首先,您可以使用以下命令计算第 1 行与所有行(关于第 3 列和第 4 列)之间的绝对差:

differences <- abs(t(t(matrix[ , 3:4]) - matrix[1, 3:4])) 

#     c3 c4
# r1   0  0
# r2  39 36
# r3 124 44
# r4   9 11
# r5  75 17

现在您可以按照第一列 (c3) 和第二列 (c4) 对这些差异进行排序。此订单用于订购您原来的matrix

matrix[order(differences[ , 1], differences[ , 2]), ]

#     c1  c2  c3  c4
# r1  58 169  37 104
# r4  46  92  46  93
# r2 186  70  76  68
# r5  70  -9 112  87
# r3  86 107 161  60

根据相关新示例进行更新:

differences <- abs(t(t(matrix[ , ]) - matrix[1, ])) 

#    c1 c2
# r1  0  0
# r2  4  7
# r3  1 13
# r4 11 87

matrix[order(differences[ , 1], differences[ , 2]), ]

#    c1 c2
# r1 10  4
# r3  9 17
# r2  6 11
# r4 21 91

【讨论】:

你摇滚。我知道了。:)【参考方案2】:

假设 c3c4 是第 3 列和第 4 列,使用 apply 计算第 1 行和其他行之间的绝对差值之和。在apply 调用的函数中,r 是每一行的向量:

> apply(matrix,1,function(r)sum(abs(r[3:4]-matrix[1,3:4])))
 r1  r2  r3  r4  r5 
  0  75 168  20  92 

第一个为零,这很好,因为那是第 1 行与其自身的绝对差之和。所以继续:

> diffs = apply(matrix,1,function(r)sum(abs(r[3:4]-matrix[1,3:4])))
> diffs
 r1  r2  r3  r4  r5 
  0  75 168  20  92 

要找到最小的索引,忽略零,去掉第一个元素,找到第一个最小的(如果有关系,这只会取一个...)并添加一个:

> 1+which(diffs[-1]==min(diffs[-1]))[1]
r4 
 4 

通过增加 sum abs diff 重新排序矩阵:

> order(diffs)
[1] 1 4 2 5 3
> matrix[order(diffs),]
    c1  c2  c3  c4
r1  58 169  37 104
r4  46  92  46  93
r2 186  70  76  68
r5  70  -9 112  87
r3  86 107 161  60

【讨论】:

以上是关于找到根据矩阵中特定列中的行之间的绝对差排序的子集的主要内容,如果未能解决你的问题,请参考以下文章

根据列中的条件对数据框中的行进行子集/过滤

Pandas:使用 apply 将特定列中的行值复制到新列中

在 txt 文件中的不同列中取两个特定值之间的行 [关闭]

选择顶部的行,直到特定列中的值出现两次

在列中查找字母并提取包含特定字母的行

查找特定列中的最小值和矩阵中相应的行号