在向量中的下一个更高值之前查找值的数量
Finding number of values before the next higher value in vector
假设我有一个向量 v=c(10,3,5,1,12,7,9,2)
。对于每个值,我想找到“下一个更高”之前的步数,即优于当前值的下一个值。
例如,第一个值是 10,下一个更高的值是 12,而 12 是从 10 减去 4 步。所以第一个元素与 4 关联。接下来,我们有一个 3,然后是 5 :距离下一个更高的值只有一步。因此,最终结果应该是 c(4,1,2,1,NA,1,NA,NA)
,每当没有“下一个更高”值时插入 NA:12 永远不会被击败,最后的 2 和它之前的 9 也不会被击败。
我可以用 'for' 循环来做到这一点:
v=c(10,3,5,1,12,7,9,2)
# stop 1 step before the last
n=length(v)-1
#initialize vector
next_higher=vector()
for (i in 1:n) {
# check if the next higher exists: the vector of higher values is non-empty
if (length(which(v[(i+1):(n+1)]>v[i]))==0) {
# if not, insert NA
next_higher=c(next_higher,NA_real_)
} else {
# else, get the index and move on
next_higher=c(next_higher,which(v[(i+1):(n+1)]>v[i])[1])
}
}
# the last one is always going to be NA
next_higher=c(next_higher,NA)
但这是出了名的低效和不优雅。
我也试过递归函数:
find_next_higher = function (x) {
# recursive function
ifelse(length(x)==1,
# if length is 1 there's no next higher
return(NA_real_),
# else check if there is a next higher
ifelse(length(which(x[-1]>x[1]))==0,
# if it doesn't exist, return NA and concatenate, removing the first element
return(c(NA_real_,find_next_higher(x[-1]))),
# if it does, find index and concatenate, removing the first element
return(c(which(x[-1]>x[1])[1],find_next_higher(x[-1])))
)
)
}
但是我遇到了一个深度递归问题,它不适用于大向量。
最干净的方法是什么?
我考虑过 apply
函数族或 purrr
库,但未能找到一种方法来处理每个值而不是单独处理剩余的 v[(n+1):length(v)]
子向量.
提前感谢您的建议。
我们可以遍历向量序列(sapply
),通过与当前元素(v[i]
比较得到'v'子集的第一个元素的位置索引) 使用 which
,对第一个位置 ([1]
) 和索引 return 进行子集化。
sapply(seq_along(v), \(i) which(v[-(seq_len(i))] > v[i])[1])
[1] 4 1 2 1 NA 1 NA NA
\(i)
是 R
最新版本中 lambda 表达式的紧凑选项。如果我们有较旧的 R
版本,请按照 News 4.1.0
中的通知使用 function(i)
R now provides a shorthand notation for creating functions, e.g. (x) x + 1 is parsed as function(x) x + 1.
sapply(seq_along(v), function(i) which(v[-(seq_len(i))] > v[i])[1])
假设我有一个向量 v=c(10,3,5,1,12,7,9,2)
。对于每个值,我想找到“下一个更高”之前的步数,即优于当前值的下一个值。
例如,第一个值是 10,下一个更高的值是 12,而 12 是从 10 减去 4 步。所以第一个元素与 4 关联。接下来,我们有一个 3,然后是 5 :距离下一个更高的值只有一步。因此,最终结果应该是 c(4,1,2,1,NA,1,NA,NA)
,每当没有“下一个更高”值时插入 NA:12 永远不会被击败,最后的 2 和它之前的 9 也不会被击败。
我可以用 'for' 循环来做到这一点:
v=c(10,3,5,1,12,7,9,2)
# stop 1 step before the last
n=length(v)-1
#initialize vector
next_higher=vector()
for (i in 1:n) {
# check if the next higher exists: the vector of higher values is non-empty
if (length(which(v[(i+1):(n+1)]>v[i]))==0) {
# if not, insert NA
next_higher=c(next_higher,NA_real_)
} else {
# else, get the index and move on
next_higher=c(next_higher,which(v[(i+1):(n+1)]>v[i])[1])
}
}
# the last one is always going to be NA
next_higher=c(next_higher,NA)
但这是出了名的低效和不优雅。
我也试过递归函数:
find_next_higher = function (x) {
# recursive function
ifelse(length(x)==1,
# if length is 1 there's no next higher
return(NA_real_),
# else check if there is a next higher
ifelse(length(which(x[-1]>x[1]))==0,
# if it doesn't exist, return NA and concatenate, removing the first element
return(c(NA_real_,find_next_higher(x[-1]))),
# if it does, find index and concatenate, removing the first element
return(c(which(x[-1]>x[1])[1],find_next_higher(x[-1])))
)
)
}
但是我遇到了一个深度递归问题,它不适用于大向量。
最干净的方法是什么?
我考虑过 apply
函数族或 purrr
库,但未能找到一种方法来处理每个值而不是单独处理剩余的 v[(n+1):length(v)]
子向量.
提前感谢您的建议。
我们可以遍历向量序列(sapply
),通过与当前元素(v[i]
比较得到'v'子集的第一个元素的位置索引) 使用 which
,对第一个位置 ([1]
) 和索引 return 进行子集化。
sapply(seq_along(v), \(i) which(v[-(seq_len(i))] > v[i])[1])
[1] 4 1 2 1 NA 1 NA NA
\(i)
是 R
最新版本中 lambda 表达式的紧凑选项。如果我们有较旧的 R
版本,请按照 News 4.1.0
function(i)
R now provides a shorthand notation for creating functions, e.g. (x) x + 1 is parsed as function(x) x + 1.
sapply(seq_along(v), function(i) which(v[-(seq_len(i))] > v[i])[1])