Мы можем адаптировать Rcpp
версию order()
из этого ответа (чтобы учесть тот факт, что вы не хотите проверять наличие дубликатов и добавлять функцию в заказ на порядок упорядочить), чтобы сделать следующее Rcpp
решение:
#include <Rcpp.h>
Rcpp::IntegerVector order(const Rcpp::NumericVector& x) {
return Rcpp::match(Rcpp::clone(x).sort(), x);
}
Rcpp::IntegerVector order(const Rcpp::IntegerVector& x) {
return Rcpp::match(Rcpp::clone(x).sort(), x);
}
// [[Rcpp::export]]
Rcpp::NumericVector foo(const Rcpp::NumericVector x,
const Rcpp::NumericVector y) {
return x[order(order(y))-1];
}
Тогда мы получим ожидаемые результаты:
library(Rcpp)
sourceCpp("foo.cpp")
vec1 <- c(0, 1, 2, 3, 4, 5, 6, 7, 9)
vec2 <- c(1, 2, 7, 5, 3, 6, 80, 4, 8)
foo(vec1, vec2)
# [1] 0 1 6 4 2 5 9 3 7
с приличной производительностью (сравнение с R-решениями, представленными другими ответами ):
benchmarks <- bench::mark(match = vec1[match(vec2, sort(vec2))],
rank = vec1[rank(vec2)],
order_order = vec1[order(order(vec2))],
rcpp_order_order = foo(vec1, vec2),
iterations = 10000)
benchmarks[ , 1:3]
# # A tibble: 4 x 3
# expression min median
# <bch:expr> <bch:tm> <bch:tm>
# 1 match 28.4µs 31.72µs
# 2 rank 7.99µs 9.84µs
# 3 order_order 26.27µs 30.61µs
# 4 rcpp_order_order 2.51µs 3.23µs
Обратите внимание, что это решение работает только при отсутствии дубликатов. (Если вы можете столкнуться с дубликатами, добавление проверки показано в связанном ответе). Также обратите внимание, что эти тесты были только сделаны на этих данных; Я не знаю точно, как они меняются в масштабе.