使用 R 将一个向量中的元素在另一向量中的位置

Mar*_*ler 5 r

我希望创建一个从一个到另一个vector的职位。这类似于以下问题:elementsvectorvector

获取一个向量在另一个向量中的值的索引?

是否有 R 函数用于查找向量中元素的索引?

matchbase 中的函数在R最简单的情况下工作,如下所示:

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,3,4,5)
desired.output <- c(1,3,5,7,9)
match(b,a)
#[1] 1 3 5 7 9
Run Code Online (Sandbox Code Playgroud)

但是,match在如下所示的更复杂的情况下似乎不起作用。which我可能需要和的组合match。到目前为止,在我考虑的每种情况下, 中的值b出现的频率并不b比 中出现的频率高a。我需要一个基本R解决方案。

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,2,3,4,5)
desired.output <- c(1,3,4,5,7,9)

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,2,3,4,4,5)
desired.output <- c(1,3,4,5,7,8,9)

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,2,3,4,4,5,5)
desired.output <- c(1,3,4,5,7,8,9,10)

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,1,2,2,3,4,4,5,5)
desired.output <- c(1,2,3,4,5,7,8,9,10)

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,1,2,2,3,3,4,4,5,5)
desired.output <- c(1,2,3,4,5,6,7,8,9,10)
Run Code Online (Sandbox Code Playgroud)

GKi*_*GKi 5

对于给定的情况pmatch将给出所需的结果。match与 结合make.unique也将起作用。如果速度很重要,可以使用或者可以split使用的功能。Rcpp另请参阅有效匹配另一个向量中向量的所有值

pm <- function(x, y) {
    a <- split(seq_along(x), x)
    b <- split(seq_along(y), y)[names(a)]
    b[lengths(b)==0] <- NA
    b <- unlist(Map(`length<-`, b, lengths(a)), FALSE, FALSE)
    `[<-`(b, unlist(a, FALSE, FALSE), b) }

Rcpp::sourceCpp(code=r"(
#include <Rcpp.h>
#include <unordered_map>
#include <queue>

using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector pmC(NumericVector a, NumericVector b) {
  IntegerVector idx(no_init(a.size()));
  std::unordered_map<float, std::queue<int> > lut;
  for(int i = 0; i < b.size(); ++i) lut[b[i]].push(i);
  for(int i = 0; i < idx.size(); ++i) {
    auto search = lut.find(a[i]);
    if(search != lut.end() && search->second.size() > 0) {
      idx[i] = search->second.front() + 1;
      search->second.pop();
    } else {idx[i] = NA_INTEGER;}
  }
  return idx;
}
)")
Run Code Online (Sandbox Code Playgroud)
a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,3,4,5)
pmatch(b,a)
match(make.unique(as.character(b)), make.unique(as.character(a)))
pm(b,a)
pmC(b,a)
#[1] 1 3 5 7 9

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,2,3,4,5)
pmatch(b,a)
match(make.unique(as.character(b)), make.unique(as.character(a)))
pm(b,a)
pmC(b,a)
#[1] 1 3 4 5 7 9

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,2,3,4,4,5)
pmatch(b,a)
match(make.unique(as.character(b)), make.unique(as.character(a)))
pm(b,a)
pmC(b,a)
#[1] 1 3 4 5 7 8 9

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,2,2,3,4,4,5,5)
pmatch(b,a)
match(make.unique(as.character(b)), make.unique(as.character(a)))
pm(b,a)
pmC(b,a)
#[1]  1  3  4  5  7  8  9 10

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,1,2,2,3,4,4,5,5)
pmatch(b,a)
match(make.unique(as.character(b)), make.unique(as.character(a)))
pm(b,a)
pmC(b,a)
#[1]  1  2  3  4  5  7  8  9 10

a <- c(1,1,2,2,3,3,4,4,5,5)
b <- c(1,1,2,2,3,3,4,4,5,5)
pmatch(b,a)
match(make.unique(as.character(b)), make.unique(as.character(a)))
pm(b,a)
pmC(b,a)
# [1]  1  2  3  4  5  6  7  8  9 10
Run Code Online (Sandbox Code Playgroud)