按 R 中的行条件子集
Subsetting by row condition in R
我正在尝试找出一种方法来对纯数字矩阵(即没有 column/row 名称)进行子集化。为了以工作示例的形式进行说明,我想删除不符合逻辑条件的行。
set.seed(42)
m <- matrix(sample.int(100, 10*10, TRUE), 10, 10)
假设我想制作一个子集,所以我保留最大行值为 90 或以上的行,但删除不满足此条件的行。
我能想到的唯一方法是通过 if/else 循环 (max(m[i,]) > 90
),但我觉得必须有更优雅的方法来做到这一点。
有什么想法吗?
您可以分几步完成。
首先,使用 apply
在行上找到行的最大值:
maxima = apply(m, 1, max)
# [1] 92 99 99 98 93 96 98 91 98 84
接下来,获取那些大于您的阈值的:
above = maxima >= 90
# [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
现在,使用它来对您的数据进行子集化:
m[above, ]
或者,在一行中:
m[apply(m, 1, max) >= 90, ]
条件可以任意扩展。例如,要测试最大值是否在 两个值之间,您可以这样做:
between = function (x, lower, upper)
x >= lower & x <= upper
m[between(apply(m, 1, max), 90, 97), ]
您可以使用 m >= 90
简单地创建一个逻辑矩阵。这是可能的,因为 >
是具有 matrix
方法的通用函数(有关具有类似行为的其他函数,请参见 ?S4groupGeneric
)。然后,我们可以 运行 rowSums
检查条件是否适用,例如
m[rowSums(m >= 90) > 0, ]
这意味着如果 任何 值等于或高于 90,肯定最大值也更高 - 所以无需首先寻找最大值。
另一种选择是使用非常高效的 matrixStats
包及其 rowMaxs
函数
library(matrixStats)
m[rowMaxs(m) >= 90, ]
根据您的意见,这里有一个可能的矢量化范围解决方案
Maxima <- rowMaxs(m)
m[Maxima >= 90 & Maxima <= 97, ]
我正在尝试找出一种方法来对纯数字矩阵(即没有 column/row 名称)进行子集化。为了以工作示例的形式进行说明,我想删除不符合逻辑条件的行。
set.seed(42)
m <- matrix(sample.int(100, 10*10, TRUE), 10, 10)
假设我想制作一个子集,所以我保留最大行值为 90 或以上的行,但删除不满足此条件的行。
我能想到的唯一方法是通过 if/else 循环 (max(m[i,]) > 90
),但我觉得必须有更优雅的方法来做到这一点。
有什么想法吗?
您可以分几步完成。
首先,使用 apply
在行上找到行的最大值:
maxima = apply(m, 1, max)
# [1] 92 99 99 98 93 96 98 91 98 84
接下来,获取那些大于您的阈值的:
above = maxima >= 90
# [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
现在,使用它来对您的数据进行子集化:
m[above, ]
或者,在一行中:
m[apply(m, 1, max) >= 90, ]
条件可以任意扩展。例如,要测试最大值是否在 两个值之间,您可以这样做:
between = function (x, lower, upper)
x >= lower & x <= upper
m[between(apply(m, 1, max), 90, 97), ]
您可以使用 m >= 90
简单地创建一个逻辑矩阵。这是可能的,因为 >
是具有 matrix
方法的通用函数(有关具有类似行为的其他函数,请参见 ?S4groupGeneric
)。然后,我们可以 运行 rowSums
检查条件是否适用,例如
m[rowSums(m >= 90) > 0, ]
这意味着如果 任何 值等于或高于 90,肯定最大值也更高 - 所以无需首先寻找最大值。
另一种选择是使用非常高效的 matrixStats
包及其 rowMaxs
函数
library(matrixStats)
m[rowMaxs(m) >= 90, ]
根据您的意见,这里有一个可能的矢量化范围解决方案
Maxima <- rowMaxs(m)
m[Maxima >= 90 & Maxima <= 97, ]