在向量中查找第一个大于 X 的值的位置
Find position of first value greater than X in a vector
我有一个向量,想找到第一个大于 100 的值的位置。
# Randomly generate a suitable vector
set.seed(0)
v <- sample(50:150, size = 50, replace = TRUE)
min(which(v > 100))
假设值是你的向量。
firstGreatearThan <- NULL
for(i in seq(along=values)) {
if(values[i] > 100) {
firstGreatearThan <- i
break
}
}
查看 which.max
:
x <- seq(1, 150, 3)
which.max(x > 100)
# [1] 35
x[35]
# [1] 103
解决方法有很多,还有一个是:
x <- 90:110
which(x > 100)[1]
大多数基于 which
和 max
的答案都很慢(尤其是对于长向量),因为它们遍历 整个 向量:
x>100
评估向量中的每个 值,看它是否符合条件
which
和 max
/min
搜索 所有 在第 1 步 return 编辑的索引,并找到 maximum/minimum
Position
只会评估条件,直到它遇到第一个 TRUE 值并立即 return 相应的索引,而不继续通过向量的其余部分。
# Randomly generate a suitable vector
v <- sample(50:150, size = 50, replace = TRUE)
Position(function(x) x > 100, v)
顺便提一下,Hadley Wickham 已经实现了一个函数 detect_index
,以在他的 purrr
函数式编程包中完成这个任务。
我最近用过 detect_index
自己,会推荐给遇到同样问题的其他人。
可在此处找到 detect_index
的文档:https://rdrr.io/cran/purrr/man/detect.html
因为我需要在一个循环中多次执行类似的计算,所以我很想知道这个线程中提供的许多答案中哪一个最有效。
TLDR:
无论第一个值在向量中出现得早还是晚,which.max(v > 100)
是解决此问题的最快方法。
但是请注意,如果v
中没有条目超过100,它将return 1;因此可能有理由
SafeWhichMax <- function (v) {
first <- which.max(v > 100)
if (first == 1L && v[1] <= 100) NA else first
}
SafeWhichMax(100) # NA
SafeWhichMax(101) # 1
如果向量很长并且不能保证包含任何 TRUE
结果,match(TRUE, v > 100)
可能比 which.max()
检查更快。
# Short vector:
v <- 0:105
microbenchmark(
which.max(v > 100),
match(TRUE, v > 100),
min(which(v > 100)),
which(v > 100)[1],
Position(function(x) x, v > 100),
Position(function(x) x > 100, v),
purrr::detect_index(v, function (x) x > 100)
)
Unit: microseconds
mean median
which.max(v > 100) 24.112 23.80
SafeWhichMax(v) 24.889 24.25
match(TRUE, v > 100) 34.752 33.20
min(which(v > 100)) 25.506 25.20
which(v > 100)[1] 25.320 24.90
Position(function(x) x, v > 100) 3231.783 3043.50
Position(function(x) x > 100, v) 3487.805 3314.75
purrr::detect_index 16436.579 16064.90
# Long vector, with late first occurrence of v > 100
v <- -10000:105
Unit: microseconds
mean median
which.max(v > 100) 24.958 24.30
SafeWhichMax(v) 25.456 24.90
match(TRUE, v > 100) 37.680 37.85
min(which(v > 100)) 26.439 26.00
which(v > 100)[1] 25.724 25.55
Position(function(x) x, v > 100) 3224.240 3036.50
Position(function(x) x > 100, v) 3389.538 3287.05
purrr::detect_index 17344.706 15283.35
我有一个向量,想找到第一个大于 100 的值的位置。
# Randomly generate a suitable vector
set.seed(0)
v <- sample(50:150, size = 50, replace = TRUE)
min(which(v > 100))
假设值是你的向量。
firstGreatearThan <- NULL
for(i in seq(along=values)) {
if(values[i] > 100) {
firstGreatearThan <- i
break
}
}
查看 which.max
:
x <- seq(1, 150, 3)
which.max(x > 100)
# [1] 35
x[35]
# [1] 103
解决方法有很多,还有一个是:
x <- 90:110
which(x > 100)[1]
大多数基于 which
和 max
的答案都很慢(尤其是对于长向量),因为它们遍历 整个 向量:
x>100
评估向量中的每个 值,看它是否符合条件which
和max
/min
搜索 所有 在第 1 步 return 编辑的索引,并找到 maximum/minimum
Position
只会评估条件,直到它遇到第一个 TRUE 值并立即 return 相应的索引,而不继续通过向量的其余部分。
# Randomly generate a suitable vector
v <- sample(50:150, size = 50, replace = TRUE)
Position(function(x) x > 100, v)
顺便提一下,Hadley Wickham 已经实现了一个函数 detect_index
,以在他的 purrr
函数式编程包中完成这个任务。
我最近用过 detect_index
自己,会推荐给遇到同样问题的其他人。
可在此处找到 detect_index
的文档:https://rdrr.io/cran/purrr/man/detect.html
因为我需要在一个循环中多次执行类似的计算,所以我很想知道这个线程中提供的许多答案中哪一个最有效。
TLDR:
无论第一个值在向量中出现得早还是晚,which.max(v > 100)
是解决此问题的最快方法。
但是请注意,如果v
中没有条目超过100,它将return 1;因此可能有理由
SafeWhichMax <- function (v) {
first <- which.max(v > 100)
if (first == 1L && v[1] <= 100) NA else first
}
SafeWhichMax(100) # NA
SafeWhichMax(101) # 1
如果向量很长并且不能保证包含任何 TRUE
结果,match(TRUE, v > 100)
可能比 which.max()
检查更快。
# Short vector:
v <- 0:105
microbenchmark(
which.max(v > 100),
match(TRUE, v > 100),
min(which(v > 100)),
which(v > 100)[1],
Position(function(x) x, v > 100),
Position(function(x) x > 100, v),
purrr::detect_index(v, function (x) x > 100)
)
Unit: microseconds
mean median
which.max(v > 100) 24.112 23.80
SafeWhichMax(v) 24.889 24.25
match(TRUE, v > 100) 34.752 33.20
min(which(v > 100)) 25.506 25.20
which(v > 100)[1] 25.320 24.90
Position(function(x) x, v > 100) 3231.783 3043.50
Position(function(x) x > 100, v) 3487.805 3314.75
purrr::detect_index 16436.579 16064.90
# Long vector, with late first occurrence of v > 100
v <- -10000:105
Unit: microseconds
mean median
which.max(v > 100) 24.958 24.30
SafeWhichMax(v) 25.456 24.90
match(TRUE, v > 100) 37.680 37.85
min(which(v > 100)) 26.439 26.00
which(v > 100)[1] 25.724 25.55
Position(function(x) x, v > 100) 3224.240 3036.50
Position(function(x) x > 100, v) 3389.538 3287.05
purrr::detect_index 17344.706 15283.35